【发布时间】:2012-05-31 12:29:46
【问题描述】:
我有一个电子商务网站,当用户登录时,他们可以使用保存的信用卡数据进行购买。所以,我想使用安全会话。
但是,我的网站上有非 SSL 页面,用户也需要在这些页面上登录。所以我也想要这个用户的不安全会话。
如何使用 Rails 做到这一点?
【问题讨论】:
标签: ruby-on-rails session
我有一个电子商务网站,当用户登录时,他们可以使用保存的信用卡数据进行购买。所以,我想使用安全会话。
但是,我的网站上有非 SSL 页面,用户也需要在这些页面上登录。所以我也想要这个用户的不安全会话。
如何使用 Rails 做到这一点?
【问题讨论】:
标签: ruby-on-rails session
您已经正确地意识到在标准 Rails 应用程序中混合 http 和 https 的问题是会话需要不安全(即通过不安全的 cookie 引用),这意味着它容易受到会话侧劫持。
正如您在对@nmott 的回答的评论中提到的,一种方法是同时使用安全和不安全的cookie。
为了我的目的,与其引用两个相同的会话,我发现拥有一个不安全的 Rails 会话以及仅引用当前登录用户的 user_id 的安全签名 cookie 就足够了。换句话说,我不需要会话的完整副本,只需要与不安全会话匹配的每个用户(在安全 cookie 中)的唯一内容。
在通过 SSL 访问的每个操作(并且具有当前用户)中,我检查安全签名 cookie user_id 是否与存储在不安全 Rails 会话中的 user_id 匹配。如果有匹配,我假设一切都很好,并通过引用不安全的会话正常进行。如果不匹配,则显示错误消息。我使用如下的 before_filter 方法完成此操作:
def verify_secure_user_cookie
# If we have a current user and the request is SSL, we want to make sure the user
# has a secure cookie that matches the current user's id. This prevents attackers
# from side-jacking a session by obtaining a cookie from a non-SSL request.
if current_user and request.ssl?
unless cookies.signed[:user_id] == current_user.id
raise StandardError, "Invalid secure user cookie"
end
end
end
据推测,合法用户将始终拥有安全 cookie,并且永远不会看到错误消息。攻击者只能复制不安全的 cookie,而无法访问安全的 cookie。在这种情况下,他可以劫持会话并访问非 SSL 页面,但无法使用受害者的会话访问 SSL 页面。
因此,您的非 SSL 页面仍然容易受到侧劫持,但您的 SSL 页面不易受到会话侧劫持的攻击。为了使其有效,您必须对所有需要安全的操作(来自窃听或来自会话侧劫持)强制执行 SSL。在控制器中使用 force_ssl 是执行此操作的一种方法,或者您可以自己滚动。
【讨论】:
在 Rails 中,您可以为任何控制器强制 SSL:
force_ssl
这会将与控制器操作相关的任何http 调用自动重定向到https。这与任何您想要实现的身份验证都是分开的。
只需对需要它的控制器实施身份验证,包括非 SSL 控制器,并为任何额外需要安全会话的控制器使用 force_ssl。
【讨论】:
config.force_ssl = true 添加到config/application.rb,有没有办法选择性地告诉控制器操作不要使用ssl?
force_ssl :except => :index 放入特定控制器可能会覆盖全局配置。