我正在使用Devise测试我的网站,我发现如果我在Devise Sign Out之后拦截重定向,而正在调用“destroy”方法,我仍然可以使用后退按钮并重新登录进入系统。
更多细节:
1)我正在使用具有以下选项的Devise :: database_authenticatable,:recoverable,:trackable,:validatable,:lockable,:timeoutable,:password_archivable,:maximum_attempts => 4,:unlock_strategy => :没有。另外,我使用sign_out_all_scopes的默认设置(true)。
2)我正在使用Burp Proxy拦截从服务器返回浏览器的呼叫。
3)我的Session Controller Destroy方法如下:
def destroy
Rails.logger.info "RESETTING SESSION"
reset_session
Rails.logger.info "DESTROYING DEVISE SESSION"
super
Rails.logger.info "DONE WITH DEVISE"
end
日志调用仅供我使用,我也尝试过使用和不使用reset_session。
4)我以用户身份登录,然后单击我的注销调用,我看到在Web服务器上调用Destroy方法(查看日志),但我拦截了对浏览器的调用。
5)点击后退按钮,我可以回到网站,我可以像我从未注销一样浏览它。
在我看来,尽管在幕后调用Warden的注销,它实际上做了任何事情,除非在浏览器上销毁cookie。另外看起来更接近,看起来Devise或Warden在注销时对数据库没有任何作用,这意味着退出但不会破坏cookie无论如何都不会产生影响。
我对Rails相对较新,对Devise来说很新,所以我只是错过了一些东西吗?
编辑:所以在与Billy Chen进行简短的对话后,我似乎没有做错任何事,这就是Devise / Warden的工作原理。我很好奇是如何解决这个问题的网站,他们希望确保注销真正注销用户?在登录/注销时更新的User对象上的状态会很容易,但我很好奇为什么在当前设计中没有选择这样做(即使它只是可选的)。
编辑2:
解决了这个问题。尽管没有:在用户模型中打开记忆,devise.rb文件有“config.use_salt_as_remember_token = true”,删除此修复了问题。如果模型不允许记忆,不完全确定为什么应该使用该配置,但至少问题已解决。
编辑3:
显然我是个骗子,它没有修复我刚刚错过拦截burp proxy中的响应。重新测试显示这仍然是一个问题。通过使用键标记用户并在注销时删除它来修复它。一个黑客,但它应该解决问题。
答案 0 :(得分:0)
“破坏”是破坏会话,而不是用户。那么为什么你期望这个“破坏”行动中的数据库操作呢?
当用户登录时,他会在登录页面填写电子邮件和密码,即“Session#new”。
当他点击“登录”按钮时,请求被发送到“Session#create”。如果登录信息正确,则建立会话。服务器发送一个包含会话ID的cookie,该会话ID是包含用户ID的哈希。
此后,此用户发出的每个请求都会向浏览器发送请求以及此cookie。服务器解码此哈希并从数据库加载用户ID。
如果他想退出,他会点击“注销”按钮,向“Session#destroy”发送“DELETE”请求,然后服务器会要求他的浏览器从该cookie中删除密钥/ id。
现在会话被销毁了。此用户无法再访问登录用户的受保护资源,因为此后发送的请求将不包含其有效的用户信息。
基本上它是如何运作的。您可以在这里查看详细信息: http://guides.rubyonrails.org/security.html