我正在构建一个使用基本身份验证的小型API。我所做的是,用户可以生成用户名和密码,可用于对API进行身份验证。
但是我发现它不能按预期100%工作。即使用户名与密码不匹配,似乎请求仍会漏掉。但是,如果密码不正确,它将被阻止。
示例:
用户名:foo
密码:bar
作品:
curl -u foo:bar http://api/protected
作品 - 但不应该:
curl -u f:bar http://api/protected
不起作用 - 按预期:
curl -u foo:b http://api/protected
对我来说,它似乎只验证密码,并忽略用户名。这是一些代码。
# Authentication
protected
def authenticate
authenticate_or_request_with_http_basic do |username, password|
@user = User.includes(:keys).find_by( :keys => { :api_key => password } )
@user.keys.each do |key|
username == key.api_id && password == key.api_key
end
end
end
答案 0 :(得分:1)
@user.keys.each do |key|
username == key.api_id && password == key.api_key
end
这段代码返回.each
的值,这是它被调用的集合(在这种情况下为@user.keys
)。由于它是一个真正的值,无论在块中评估条件的结果如何,检查都将始终通过。
您打算问的是“用户的任何密钥是否与这些凭据匹配?”。使用适当的方法Enumerable#any?
@user.keys.any? do |key|
username == key.api_id && password == key.api_key
end
答案 1 :(得分:0)
试试这个
@user = User.includes(:keys).find_by( :keys => { :api_key => password, :api_id => username } )
这样您就可以确保找到有效username
和password
的用户,并且您不需要第二行(迭代键)。
原因是:遍历块返回此块,而不是内部的值/值。因此,您的身份验证器找到了一个密码好的用户,迭代了他的密钥(没有改变任何内容)并返回@user.keys
,其评估为true
。因此认证通过了。