使用Rails进行安全且不安全的会话

我有一个电子商务网站,当用户登录时,他们可以使用保存的信用卡数据进行购买。 所以,我想使用安全会话。

但是,我在网站上有非SSL页面,用户也需要登录这些页面。 所以我也希望为这个用户提供一个不安全的会话。

我怎么能用Rails做到这一点?

您已经正确地意识到在标准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 。 这与您想要的任何身份validation分开。

只需为需要它的控制器实现身份validation,包括非ssl控制器,并对任何需要安全会话的控制器使用force_ssl