在Rails中,我为用户身份验证实现了以下代码(确认为正确)。但是,我想证实我对这个奇怪的session[:session_token]
的想法。这是" cookie"那存储在浏览器中?
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :current_user, :signed_in?
private
def current_user
@current_user ||= User.find_by_session_token(session[:session_token])
end
def signed_in?
!!current_user
end
def sign_in(user)
@current_user = user
session[:session_token] = user.reset_token!
end
def sign_out
current_user.try(:reset_token!)
session[:session_token] = nil
end
def require_signed_in!
redirect_to new_session_url unless signed_in?
end
end
到目前为止,我对其工作原理的理解是,每当浏览器/客户端向rails发送请求时,cookie(带有session[:session_token]
)也会被发送,从而允许current_user
方法找到用户。我的理解是否正确?这对我来说很奇怪,因为当我们在ApplicationController(Rails-side)中声明它时,浏览器/客户端如何准确访问会话cookie的知识差距。
答案 0 :(得分:8)
你几乎就在那里。虽然,我有一种感觉,你可能会混淆苹果与橘子......
<强> 会话: 强>
通常在动态网站中,人们会希望在HTTP请求之间存储用户数据(因为http是无状态的,否则您无法将请求与任何其他请求相关联),但您不希望这样数据在URL内部的客户端可读和/或可编辑(例如.. yourwebsite.com/yourPage?cookie=12345&id=678),等等......因为你没有希望客户端在不通过服务器端代码的情况下使用该数据。
解决这个问题的一种方法是存储数据服务器端,给它一个&#34; session_token&#34;(如你所说),让客户端只知道(并在每个http请求时传回)那个令牌。这就是会话的实现方式。
<强> 饼干: 强>
在Rails中实现会话的最常用技术涉及使用cookie,这是放在用户浏览器上的一小段文本。由于cookie从一个页面持续存储到下一个页面,因此它们可以存储可由应用程序用于从数据库中检索登录用户的信息(例如session_token或您想要的任何其他内容)。
会话存储在Rails中的哪个位置?
使用上述两个概念,我现在可以告诉你Rails中的默认会话存储是CookieStore,大小约为4KB。
简单地说......
def sign_in(user)
@current_user = user
session[:session_token] = user.reset_token!
end
...您定义的方法将用户置于临时会话中。
然后想法是以下......
def current_user
@current_user ||= User.find_by_session_token(session[:session_token])
end
...方法将从对应于会话令牌的数据库中查找并检索用户,并将其初始化为您指定的变量。
您还应该注意到Rails的session
和cookies
辅助方法之间存在重要差异......
他们都生成Cookie,但是,session[...]
方法会生成临时 Cookie,这些Cookie会在浏览器退出时到期,而cookies[...]
方法会创建持久性饼干,但没有。
此外,我建议您查看Ruby on Rails Security guide的第2部分。您可能会发现它很有用。
希望这可以帮助你。
答案 1 :(得分:0)
在 rails 服务器中设置会话时,例如:session[:user_id] = 4
,
对于每个浏览器,Rails 都会在 cookie 中设置一个 session identifier
,以便 Rails 可以找到请求的正确会话信息。
cookie 中没有 session identifier
,Rails 不知道哪个会话属于哪个浏览器。
因此,没有 cookie,会话将无法工作。