更新
我确定我可以在其他操作中更改会话,但是如果我在POST
请求中设置会话,则它不会持续。如果我将操作从POST
更改为GET
,则会话仍然存在。
原始问题:
我有一个Rails 4.2.0.rc3应用程序。每当用户登录时,会话被分配给该用户的id。但是,当我运行current_user
方法时,会话不会持续。我在secret_key_base
文件中有一个secret.yml
。这是我的Sessions Helper。
module SessionsHelper
def sign_in(user)
session[:id] = user.id
puts "signing in" * 100
puts session[:id].inspect
end
def signed_in?
current_user.present?
end
def current_user
puts "checking session" * 100
puts session[:id].inspect
Avatar.find_by(id: session[:id])
end
end
在我的日志文件中,我看到session[:id]
已设置。运行另一个操作并调用current_user
方法时,session[:id]
为零。什么错了,我该如何解决这个问题?
答案 0 :(得分:6)
Rails具有CSRF保护,但默认情况下仅应用于POST,而不是GET
在CSRF失败的情况下,defualt Rails CSRF保护逻辑将默默使用新的Session,而不是提升。 (我认为这是个人默认的糟糕选择)。
我想知道这是不是正在发生的事情。
要找出答案,你想告诉你的Rails应用程序实际上在CSRF失败时引发异常失败,而不是默默地使用新的孤立会话。
在app/controllers/application_controller.rb
中,查找行protect_from_forgery
,然后更改为protect_from_forgery with: :exception
,告诉Rails实际加注CSRF失败。 (实际上,看起来Rails 4.x应用程序现在是使用这个新版本的行生成的,但是如果你有一个应用程序,你将从3.x升级,它将不会。{{3}的Hooray } {rails}版本中rails new
生成代码的更改。
如果您在演示测试用例中遇到异常,那么就知道问题是什么,您可以找出适当的解决方案:要么使用正确的CSRF保护获取POST请求,要么为该操作关闭CSRF保护。如果它是API类型的请求,您可能不需要CSRF保护。
有关此类问题的更多背景阅读,请参阅:
那听起来像你的问题吗?
答案 1 :(得分:0)
不确定这是否是您的问题,但我记得当我看到升级到rails 4.1(表单4.0)时看到这个
以下是文档的链接和部分。我认为这只适用于4.1而不是4.0
3.5 Cookies序列化程序在Rails 4.1之前创建的应用程序使用Marshal将cookie值序列化为已签名和加密的值 饼干罐子。如果你想在你的。中使用新的基于JSON的格式 应用程序,您可以使用以下内容添加初始化程序文件 含量:
Rails.application.config.action_dispatch.cookies_serializer =:hybrid 这将透明地迁移现有的Marshal序列化 将cookie转换为基于JSON的新格式。
使用:json或:hybrid serializer时,你应该注意不要 所有Ruby对象都可以序列化为JSON。例如,日期和时间 对象将被序列化为字符串,而哈希将具有其键 字符串化。
类CookiesController< ApplicationController def set_cookie cookies.encrypted [:expiration_date] = Date.tomorrow#=> 2014年3月20日星期四 redirect_to action:'read_cookie'结束 def read_cookie cookies.encrypted [:expiration_date]#=> “2014-03-20”end end建议您只存储简单数据(字符串和数字) 在饼干中。如果必须存储复杂对象,则需要 在后续读取值时手动处理转换 请求。
如果您使用cookie会话存储,这将适用于会话 和闪存哈希。