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/