ruby - 是否有一个 Rack 中间件可以在没有 cookie 的情况下使用 session ?

标签 ruby session cookies rack

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

所以我的问题是 - 是否有一个项目维护替代的 Rack 中间件或 Rack 内置中间件的猴子补丁,这将允许我维护查询字符串上的 session ID,而不是 cookie 存储?

最佳答案

Rack 可以使用自定义 session ID 项代替 cookie:

require 'rack/session/abstract/id'

Rack 文档可能是您开始搜索的一个有用的地方。我相信您正在寻找“跳过”选项(或“延迟”选项)。

文档:

ID 为实现基于 id 的 session 设置了一个基本框架 服务。发送给客户端用于维护 session 的 Cookie 只会 包含一个 id 引用。只有#get_session 和#set_session 是 需要覆盖。

所有参数都是可选的。

  • :key 决定cookie的名称,默认为 'rack.session'
  • :path, :domain, :expire_after, :secure, :httponly 设置相关 由 Rack::Response#add_cookie
  • 提供的 cookie 选项
  • :skip 不会在响应中设置 cookie 也不会更新 session 状态
  • :defer 不会在响应中设置 cookie 但仍会更新 session 说明它是否与后端一起使用
  • :renew(依赖于实现)会提示生成一个新的 session id,迁移数据到新id引用。如果 :defer 已设置,它将被覆盖并设置 cookie。
  • :sidbits 设置生成的 session 的长度位数 id 将是。

这些选项可以在每个请求的基础上设置,在 env['rack.session.options']。此外, session 的 ID 可以是 在关键字 :id 的选项散列中找到。这是非常不 建议更改其值。

Rack::Utils::Context 是否兼容。

默认不包含;你必须要求'rack/session/abstract/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

关于ruby - 是否有一个 Rack 中间件可以在没有 cookie 的情况下使用 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15500041/

相关文章:

python - scrapy - 从响应/请求 header 获取cookie

javascript - 如何在浏览器中读取 Connect Js cookie?

java - java中如何设置多个cookie?

ruby-on-rails - rails 4中secret_key_base有什么用

ruby-on-rails - 在 Rails 中为新手创建登录的最佳方式是什么?

php - 我如何找到 php session 开始时间戳

iOS/watchos2 - 为什么没有 session :didReceiveApplicationContext: fire?

ruby-on-rails - 从 ActiveRecord_Associations_CollectionProxy 对象获取模型引用

ruby - 模块化、基于组件的 Sinatra 应用程序的架构

php - 如果用户计算机 ip 地址与允许的 ip 地址 mysql 表不匹配,则阻止登录使用 Laravel 5.4