Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 是否有机架中间件用于使用不带cookie的会话?_Ruby_Session_Cookies_Rack - Fatal编程技术网

Ruby 是否有机架中间件用于使用不带cookie的会话?

Ruby 是否有机架中间件用于使用不带cookie的会话?,ruby,session,cookies,rack,Ruby,Session,Cookies,Rack,Rack附带的会话管理中间件都基于用于识别用户的cookie。因为我正在开发一个api,所以我宁愿将会话id显式地作为查询字符串参数传递。从代码库来看,似乎没有考虑这个用例,因为所有会话中间件都是从一个公共类扩展而来的,该类读取/写入cookie 因此,我的问题是-是否有一个项目维护替代机架中间件或机架内置中间件的猴子补丁,允许我在查询字符串上维护会话id,而不是cookie存储?机架可以使用自定义会话id项而不是cookie: require 'rack/session/abstract/id

Rack附带的会话管理中间件都基于用于识别用户的cookie。因为我正在开发一个api,所以我宁愿将会话id显式地作为查询字符串参数传递。从代码库来看,似乎没有考虑这个用例,因为所有会话中间件都是从一个公共类扩展而来的,该类读取/写入cookie


因此,我的问题是-是否有一个项目维护替代机架中间件或机架内置中间件的猴子补丁,允许我在查询字符串上维护会话id,而不是cookie存储?

机架可以使用自定义会话id项而不是cookie:

require 'rack/session/abstract/id'
机架文档可能是开始搜索的有用地方。我相信您正在寻找“跳过”选项(或“延迟”选项)

文件:

ID为实现基于ID的会话设置了一个基本框架 服务发送到客户端用于维护会话的Cookie仅会 包含一个id引用。只有“获取”会话和“设置”会话是可用的 需要被覆盖

所有参数都是可选的

  • :键确定cookie的名称,默认情况下为 '机架会话'
  • :path、:domain、:expire\u after、:secure和:httponly设置相关的 按机架列出的cookie选项::响应#添加cookie
  • :skip不会在响应中设置cookie,也不会更新会话状态
  • :defer不会在响应中设置cookie,但仍会更新会话 说明是否与后端一起使用
  • :续订(取决于实现)将提示生成新的 会话id,以及要在新id处引用的数据迁移。如果 :如果设置了延迟,则将覆盖它并设置cookie
  • :sidbits设置生成会话的长度位数 我会的
这些选项可以根据每个请求在 env['rack.session.options']。此外,会话的id可以是 在选项散列中的键id处找到。它不是 建议更改其值

Rack::Utils::与上下文兼容

默认不包括在内;您必须要求使用“机架/会话/摘要/id”

资料来源:

  class ID
    DEFAULT_OPTIONS = {
      :key =>           'rack.session',
      :path =>          '/',
      :domain =>        nil,
      :expire_after =>  nil,
      :secure =>        false,
      :httponly =>      true,
      :defer =>         false,
      :renew =>         false,
      :sidbits =>       128,
      :cookie_only =>   true,
      :secure_random => (::SecureRandom rescue false)
    }
我希望这能给你一个线索。。。当你了解更多信息时,你能在这里分享你的结果吗

编辑: 魔术是将选项
:cookie_only=>false
:defer=>true
组合在一起。当然,标准的Rack::Session::Cookie在这里没有多大意义,因此您可以:

use Rack::Session::Pool, :cookie_only => false, :defer => true
有趣的是,您可以在运行时更改选项。在我的用例中,我实际上需要支持传统的基于cookie的机制以及显式的参数传递样式,因此我做了以下工作:

class WebApp < Sinatra::Base

  configure do
    use Rack::Session::Pool, :key => 'session_id'
  end

  before do
    # Switch to parameter based session management if the client is an ios device
    if env['HTTP_USER_AGENT'] =~ /iOS/
      session.options[:cookie_only] = false
      session.options[:defer] = true
    end
  end

  get '/' do
    session[:user_id] ||= nil # This triggers a session-write, giving us a valid session-id
    body "session_id=#{session.id}"
  end
end
class-WebApp“Session\u id”
结束
在做之前
#如果客户端是ios设备,则切换到基于参数的会话管理
如果env['HTTP\u USER\u AGENT']=~/iOS/
session.options[:cookie_only]=false
session.options[:defer]=true
结束
结束
获取“/”do
会话[:user_id]| |=nil#这会触发会话写入,为我们提供有效的会话id
正文“session_id=#{session.id}”
结束
结束

如果您希望消除API应用程序中cookie的使用,但仍希望管理会话。例如,在我的例子中,会话标识符来自令牌。 您需要重新定义方法
extract\u session\u id
,以便从接收到的令牌中提取会话标识符。必须在会话存储类上重新定义此方法,因为
Rack::session::Abstract::ID
提供了基于cookie的默认实现。 它是从调用会话对象上的
Rack::Session::Abstract::ID#current_Session_ID
方法调用的,该方法通常由
Rack::Session::Abstract::SessionHash
实例表示。在这个
SessionHash#id
方法中,从最终调用的会话存储中提取会话id

我认为单独配置会话标识符提取器会更简单,但希望将会话标识符与会话数据一起存储在cookie中会导致这种设计被欺骗

同样,在方法
#commit_Session
#set_cookie
中的
Rack::Session::Abstract::ID
类中看到cookie交互也有点奇怪。 因此,为了完全确保不会设置cookie,您也可以在您的商店中重新定义
#set_cookie
方法。通过为会话存储中间件设置
cookie\u only:false,defer:true
,可能可以实现相同的目标,如这里的一个答案中所述,但我没有对此进行检查

当然,您需要修改中间件堆栈,以排除所有与cookie交互的中间件以及可能的特定于浏览器的中间件。在rails的默认中间件堆栈上,它可以如下所示:

# config/application.rb
[
  Rack::MethodOverride, # browser specific
  ActionDispatch::Cookies,
  ActionDispatch::Flash
].each do |middleware|
  config.middleware.delete(middleware)
end
此外,您肯定需要将会话存储替换为在服务器端存储信息的内容,例如redis:

# config/initializers/session_store.rb
Rails.application.config.session_store ::Custom::Session::TokenRedisStore
在我的例子中,
::Custom::Session::TokenRedisStore
继承了
::RedisSessionStore
并重新定义了上述所有方法。
::RedisSessionStore
包含在redis会话存储中。因此,如果要使用它,显然需要将它添加到
Gemfile


我在Rails 4.2.x中这样做了,但是在任何框架中都可以采用与
Rack
相同的方法。谢谢-这看起来是一个很好的线索。通过浏览代码,我认为我需要设置
:defer
,而不是
:skip
参数。在这个例子中,session[:user_id]在哪里设置为非nil的实际值?然后,客户机如何将会话id传递回服务器以获取该会话的值