Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 葡萄API和HTTP摘要认证_Ruby_Rubygems_Rack_Datamapper_Grape Api - Fatal编程技术网

Ruby 葡萄API和HTTP摘要认证

Ruby 葡萄API和HTTP摘要认证,ruby,rubygems,rack,datamapper,grape-api,Ruby,Rubygems,Rack,Datamapper,Grape Api,我正在为我的ruby应用程序创建一个API,它基于HTTP摘要身份验证对用户进行身份验证。我决定使用GrapeAPI库,因为它可以在ruby中创建一个API清理器。Grape文档说明您可以使用摘要身份验证,如: http_digest({ :realm => 'Test Api', :opaque => 'app secret' }) do |username| # lookup the user's password here { 'user1' => 'passwo

我正在为我的ruby应用程序创建一个API,它基于HTTP摘要身份验证对用户进行身份验证。我决定使用GrapeAPI库,因为它可以在ruby中创建一个API清理器。Grape文档说明您可以使用摘要身份验证,如:

http_digest({ :realm => 'Test Api', :opaque => 'app secret' }) do |username|
  # lookup the user's password here
  { 'user1' => 'password1' }[username]
end
上面的Grape实现是对
Rack::Auth::Digest::MD5

现在,为了安全起见,我了解到,从RFC 2617开始,您不需要在数据库中以纯文本形式存储密码,而是存储username:realm:password的MD5摘要,并对其进行身份验证,因此我创建了一个DataMapper模型:

class Key
  include DataMapper::Resource

  property :id,              Serial

  property :username,        String
  property :password,        String

  property :active,          Boolean, :default => true
  property :created_at,      DateTime, :default => DateTime.now
  property :updated_at,      DateTime
end

现在有了我所提供的,我不知道如何连接这两者并使其工作

不幸的是,
Rack::Auth::Digest::MD5
需要服务器端的明文密码

Grape示例代码显示了密码的硬编码查找

您可以将
{'user1'=>'password1'}[username]
替换为

Key.first( :username => username ).password
如果您将明文密码存储在
类中。我想,您可以存储这些可逆加密的密钥,尽管这不会增加太多安全性,除非您构建相对复杂/昂贵的密钥管理方案

不确定是否有办法让您存储散列密码。MD5不是最安全的哈希选择(尽管总比没有好!)。如果安全性是您的API的一个重要问题,那么您将希望超越摘要身份验证——例如,使用https将有所帮助

编辑:在讨论中进行了一些来回的讨论之后,Grape示例的以下变体确实允许您存储MD5的d密码:

auth :http_digest, { :realm => { :realm => 'Llama', :passwords_hashed => true, :opaque => "7302c32d39bbacb5ed0ace096723fd" } } do |username|
  Digest::MD5.hexdigest( 'fred:Llama:654321' )
end
该示例给出了一个硬编码用户名“fred”,密码“654321”响应。因此,我认为您的目标代码类似于:

auth :http_digest, { :realm => { :realm => 'Llama', :passwords_hashed => true, :opaque => "7302c32d39bbacb5ed0ace096723fd" } } do |username|
  k = Key.first( :username => username )
  k ? k.password : nil
end
然后将
摘要::MD5.hexdigest(“#{username}:#{realm}:#{password}”)的结果存储在每个用户的password属性中


注意两次使用
:realm
的双层散列。这有点粗糙,但至少您不必编写自己的中间件,Grape仍在处理它。这不是葡萄的记录特征,也没有经过测试,因此,在未来的版本中可能无法使用。

环顾四周后,我发现如果将
attr\u writer:passwords\u hashed
设置为
true
,那么它将接受格式为
username:realm:password
的已散列密码,这很好,但我无法从Grape API包装器中设置该属性。有什么建议吗?通过查看Grape代码,您可以向
:realm
符号提供一个散列,其中包含
:realm、:不透明、:密码\u散列的
键。没有记录或测试葡萄虽然,所以有点后门你想要什么。我测试了它,但它对我不起作用。我将尝试看看会发生什么,对于不透明值,它是什么有关系,我可以将它设置为
SecureRandom.hex(15)
例如吗?不完全确定
:不透明
的作用,示例只是显示客户端将其反射回服务器。不过,我刚刚在我的电脑上试用了一个迷你Grape应用程序,你的建议对我来说很好。好的,谢谢,我正在浏览Grape api和rack源代码,但是我非常不知道在哪里添加修改。