会话不会在Rails中持续4

时间:2014-12-16 19:20:57

标签: ruby-on-rails ruby session ruby-on-rails-4

更新

我确定我可以在其他操作中更改会话,但是如果我在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]为零。什么错了,我该如何解决这个问题?

2 个答案:

答案 0 :(得分:6)

嗯,由你的更新触发,这只发生在POST上,我记得不完整的几件事。

  • 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会话存储,这将适用于会话   和闪存哈希。