ruby-on-rails – Rails ActiveRecord存储和新会话

ruby-on-rails – Rails ActiveRecord存储和新会话,第1张

概述我是Rails的新手,遇到一个我不明白的奇怪问题. 我使用ActiveRecord作为会话存储,需要添加会话ID作为所有请求的 JSON响应的属性.如果它对情况有一些影响,我也会使用Devise.问题是,如果用户没有cookie(或者至少没有cookie中的会话ID)发出请求,则session.id为空或者 – 请注意 – 与响应cookie中设置的值不同. 为了调试,我将此代码作为after_f 我是Rails的新手,遇到一个我不明白的奇怪问题.
我使用ActiveRecord作为会话存储,需要添加会话ID作为所有请求的 JSON响应的属性.如果它对情况有一些影响,我也会使用Devise.问题是,如果用户没有cookie(或者至少没有cookie中的会话ID)发出请求,则session.ID为空或者 – 请注意 – 与响应cookie中设置的值不同.

为了调试,我将此代码作为after_filter添加到ApplicationController:

puts session.IDputs request.session_options[:ID]

两个值都相同.它们与cookie中的值匹配(如果存在).否则,如果cookie中不存在会话ID,则在该请求之后设置的cookie具有不同的值.

我的观点是session_ID在实际保存到数据库之后获得新值,它必须是唯一的.数据库迁移:

def change  create_table :sessions do |t|    t.string :session_ID,:null => false    t.text :data    t.timestamps  end  add_index :sessions,:session_ID,:unique => true  add_index :sessions,:updated_atend

我的问题:如何在呈现第一个响应之前获取新会话的实际session.ID值?

UPD:

我刚刚创建了一个新的Rails应用程序,该应用程序使用不带Devise的ActiveRecord会话存储,我可以获得会在使用此代码ID应用程序控制器响应之前在cookie中设置的session.ID:

class ApplicationController < ActionController::Base  after_filter :show_session  def show_session    puts session.ID  endend

但是在我使用Devise的现有应用程序中,我得到一个看起来像会话ID的值,但是它与通过Set-cookie响应头中的cookie中设置的值不匹配,并且实际保存到数据库中的会话表中的值.看起来Devise在某种程度上与ActiveRecord会话存储有冲突.需要深入了解它.

UPD 2

看起来我发现问题的根源.正如我所说,我使用Devise与Omniauth进行授权.根据文档,sign_in方法出于安全原因重置会话ID.但是在重置之后session.ID返回已经自动设置的旧值.我使用此代码作为Omniauth回调:

def facebook_access_token  sign_in @user  puts session.IDend

在控制台中,我得到的会话ID与Set-cookie响应头中设置的会话ID不同.如果我评论“sign_in”行,则这些值匹配.新问题:如何在sign_in方法内重置后获取新的会话ID值?它是内部Warden / Devise实现还是什么?

解决方法 更新仍然很重要,您不应该禁用它

此外,新的会话ID是在执行控制器之后生成的,因此在您有机会将响应设置为发送到客户端之后.

解决方案是手动触发会话ID的更新

在ApplicationController中添加方法:

protected  def commit_session_Now!    return unless session.options[:renew]    object = session.options.instance_variable_get('@by')    env = session.options.instance_variable_get('@env')    session_ID = object.send(:destroy_session,env,session.ID || object.generate_sID,session.options)    session_data = session.to_hash.delete_if { |k,v| v.nil? }    object.send(:set_session,session_ID,session_data,session.options)    session.options[:renew] = false    session.options[:ID] = session_ID  end

然后在您的控制器中,您只需在获取响应的会话ID之前调用此方法

def my_action  ...  commit_session_Now!  render Json: {session_ID: session.ID},status: :okend

commit_session_Now中的代码!来自Rack :: Session :: Abstract :: ID#commit_session https://github.com/rack/rack/blob/master/lib/rack/session/abstract/id.rb#L327

总结

以上是内存溢出为你收集整理的ruby-on-rails – Rails ActiveRecord存储和新会话全部内容,希望文章能够帮你解决ruby-on-rails – Rails ActiveRecord存储和新会话所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1281474.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存