繁体   English   中英

确定WHERE语句的哪个部分失败

[英]Determine Which Part(s) of WHERE Statement Failed

假设我有一个这样的SQL语句来检查用户登录:

SELECT * FROM users 
WHERE username='test@example.com', password='abc123', expire_date>=NOW();

SQL中是否有一种方法可以确定哪些WHERE条件失败,而不必将每个条件分成自己的查询并单独测试?

在此特定示例中,它将允许开发人员准确地告诉用户他们尝试登录失败的原因。

出于我的目的,我正在使用PHP / MySQL。

好吧,你可以做的一件事是改变你的查询,使它只匹配用户名。 然后在代码中检查密码和到期日期,返回适当的错误。

另外,我希望您的示例查询是一种简化; 当然,您应该对您的密码进行腌制/加密/散列,并且您应该包含限制在特定时间范围内失败尝试次数等的内容,等等......

就您的实际问题而言(与您正在寻找的结果相反),没有办法从where子句获取该信息。 你能做的最接近的是:

SELECT *,
    CASE WHEN Password = 'asdf' THEN 1 ELSE 0 END AS IsPasswordMatch,
    CASE WHEN Expiration >= NOW() THEN 1 ELSE 0 END AS IsActiveAccount
FROM Users
WHERE Username = 'user'

在MySQL中,您可以在选择列表中放置布尔表达式。 布尔表达式在为true时计算为整数1,在为false时计算为整数0。

SELECT password = 'abc123' AS is_authenticated,
       expire_date >= NOW() AS is_not_expired
FROM users
WHERE username='test@example.com';

注意:如果您需要编写适用于其他品牌RDBMS的查询,请记住这种布尔表达式的使用是非标准的。 使用其他人发布的CASE语法。

PS:这是你问题的一个切线,但我建议你不要用明文存储密码。 存储盐渍密码的哈希摘要。 请参阅密码盐如何帮助抵御彩虹表攻击?

不,where子句应用为块,并且使用各种技术,因此不必扫描所有行。 另外,你怎么知道哪一行是你想要的那一行?

此外,您可能不希望过多地告诉用户登录尝试失败的原因。 说太多允许利用诸如帐户挖掘和密码攻击之类的漏洞。

编辑如果您确实想要向用户显示此内容,请将逻辑拆分为不同的部分:

  1. 验证身份
    操作:从数据库中获取相应的用户行
    结果:
    • 如果没有这样的行=>帐户无效
    • 如果返回row,请继续执行步骤2。
  2. 验证凭证
    操作:根据提供的密码检查存储的凭据(密码,密码哈希或加密密码),其处理方式与存储凭证的方式相同。
    结果:
    • No match =>密码/凭证无效
    • 匹配=>成功登录尝试
  3. 登录用户
    操作:向会话等添加数据

您可能只需要将where子句的部分与'AND'分开

SELECT * FROM users 
WHERE username='test@example.com'
   And password='abc123'
   And expire_date>=NOW();

这是我想出的:

SELECT
  IF(mem_username='test@example.com','true','Error: Bad Username') AS mem_username,
  IF(mem_password ='abc123','true','Error: Bad Password') AS mem_password'
FROM MEMBERS
WHERE mem_username='test@example.com' AND mem_password='abc123'

这样我就可以在代码中检测错误消息,然后根据需要显示它们。

注意: 对于所有人都引用示例代码的安全问题,感谢您的关注。 但是,这不是真正的生产代码,这只是一个简单的例子来证明我的问题。 很明显,您不应该以明文形式存储密码,并且您不应该向用户提供有关登录失败原因的详细信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM