devise的token_authenticatable安全吗?
我正在用Rails API构build一个简单的api,并且要确保我在这里的正确轨道上。 我使用devise来处理login,并决定去devise的token_authenticatable
选项,它会生成一个API密钥,你需要发送每个请求。
我正在将API与骨干/木偶前端配对,并且通常想知道我应该如何处理会话。 我的第一个想法是将api密钥存储在本地存储或cookie中,并在页面加载时检索它,但是从安全angular度来看,存储api密钥的方式困扰了我。 通过查看本地存储/ cookie或嗅探任何经过的请求,并使用它无限地模拟该用户,将不容易抓住api密钥? 我目前正在重新设置每个login的api密钥,但即使这似乎很频繁 – 任何时候你login任何设备,这意味着你会登出每隔一个,这是一种痛苦。 如果我可以放弃这个重置,我觉得从可用性的angular度来看会有所改进。
我可能在这里完全错了(也希望是我),任何人都可以解释这种方式是否可靠地进行validation,如果不是一个好的select会是什么? 总体而言,我正在寻找一种方法,可以安全地保持用户loginAPI访问权限,而无需频繁强制重新授权。
token_authenticatable
容易受到时间攻击,这在本博客文章中有很好的解释。 这些攻击是从Devise 3.1中删除token_authenticatable
的原因。 请参阅plataformat博客文章了解更多信息。
要拥有最安全的令牌authentication机制,令牌:
-
必须通过HTTPS发送。
-
必须是随机的,密码强度。
-
必须安全地比较。
-
不得直接存储在数据库中。 只有令牌的散列可以存储在那里。 (请记住,令牌=密码。我们不在密码中以纯文本forms存储密码,对不对?)
-
应按照某种逻辑过期。
如果你放弃了一些有利于可用性的要点,那么最终会有一个机制不够安全。 就这么简单。 如果满足前三个要求并限制对数据库的访问,则应该足够安全。
扩展并解释我的答案:
-
使用HTTPS 。 这绝对是最重要的一点,因为它涉及嗅探器。
如果你不使用HTTPS,那么很多可能会出错。 例如:
-
为了安全地传输用户的凭证(用户名/电子邮件/密码),你将不得不使用摘要式身份validation,但是现在不能切断它,因为盐渍哈希可能被强制使用 。
-
在Rails 3中,Cookie只被Base64编码笼罩,所以它们可以很容易地显示出来。 有关更多信息,请参阅解码Rails会话Cookie 。
由于Rails 4,cookie存储是encryption的,所以数据既被数字validation,也不被攻击者读取。 只要您的
secret_key_base
不泄露,Cookies应该是安全的。
-
-
使用
SecureRandom.hex
生成令牌。 或者使用gemsysrandom
。显然
SecureRandom
不是那么安全。 不过,这里还有一个折衷:从标准库中挑选一些东西,或者挑选一些由某人维护的gem。 为了做出明智的决定,我build议阅读sysrandom
的自述文件和博客文章如何以各种编程语言生成安全随机数 。 -
使用用户的ID,电子邮件或其他属性查找用户logging。 然后,用
Devise.secure_compare(user.auth_token, params[:auth_token]
将该用户的令牌与请求的令牌进行Devise.secure_compare(user.auth_token, params[:auth_token]
。如果您使用的是Rails 4.2.1+,则还可以使用ActiveSupport::SecurityUtils.secure_compare
。不要使用像
User.find_by(auth_token: params[:auth_token])
这样的Rails查找器来查找用户logging。 这很容易受到时间攻击! -
如果每个用户要同时有几个应用程序/会话,则有两个选项:
-
将未encryption的令牌存储在数据库中,以便可以在设备之间共享。 这是一个不好的做法,但我想你可以用UX的名义来做(如果你相信你的员工有数据库访问)。
-
为每个用户存储尽可能多的encryption令牌,以允许当前会话。 所以如果你想在2个不同的设备上允许2个会话,在数据库中保存2个不同的令牌散列。 这个选项实现起来不那么简单,但它绝对安全。 它也有允许你提供给你的用户通过撤销令牌(就像GitHub和Facebook一样)在特定设备中结束当前活动会话的选项。
-
-
应该有某种机制导致令牌过期。 在实施这一机制时,要考虑到用户体验与安全性之间的平衡。
如果Google没有使用六个月,Google会过期 。
如果Facebook未使用两个月,Facebook会过期 :
使用Facebook SDK的原生移动应用程序将获得长达60天的访问令牌。 当使用您的应用的用户向Facebook服务器发送请求时,这些令牌每天都会刷新一次。 如果没有请求,令牌将在大约60天后过期,并且该人员将不得不再次通过loginstream来获得新的令牌。
-
升级到Rails 4以使用其encryption的cookie存储。 如果你不能,那就自己encryptioncookie存储,就像这里build议的那样。 将身份validation令牌存储在encryption的cookie存储中绝对没有问题。
您还应该有一个应急计划,例如,重置令牌的子集或数据库中的每个令牌。
为了让你开始,你可以看看这个 (由Devise的作者之一)如何实现与Devise令牌authentication的要点 。 最后, 保证API的Railscast应该是有帮助的。
根据该项目的自述文件,devise_token_auth gem受这个StackOverflow文章的启发: https : //github.com/lynndylanhurley/devise_token_auth
您可以尝试使用您的API的rails4 ,它提供了更多的安全性,并使用devise3.1.0rc
-
在Rails 4.0中,几个特性已经被提取到gem中。
- 的ActiveRecord :: SessionStore
- 行动caching
- 页面caching
- 俄罗斯娃娃通过嵌套模板的自动依赖pipe理通过基于密钥的过期进行caching。
http://blog.envylabs.com/post/41711428227/rails-4-security-for-session-cookies
-
Devise 3.1.0.rc在Rails 3.2和Rails 4.0上运行。 http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/
-
Devise是在
TokenAuthenticatable
中对TokenAuthenticatable
弃用,但是您可以构build自己的TokenAuthenticatable
方法来解决安全问题。 这更可靠和安全。
对于令牌,会话存储,你可以通过http://ruby.railstutorial.org/chapters/sign-in-sign-out和http://blog.bigbinary.com/2013/03/19/cookies-on-rails .html更可爱。
最后你应该通过这种encryption和解密“ 无法解密存储的encryption数据 ”来获得更多的安全性。