Rack 可以使用自定义会话 ID 项而不是 cookie:
require 'rack/session/abstract/id'
Rack 文档可能是您开始搜索的一个有用的地方。我相信您正在寻找“跳过”选项(或“延迟”选项)。
文档:
ID 为实现基于 id 的会话建立了一个基本框架
服务。发送给客户端用于维护会话的 Cookie 只会
包含一个 id 参考。只有 #get_session 和 #set_session 是
需要被覆盖。
所有参数都是可选的。
- :key决定cookie的名字,默认是
'机架.会话'
- :path, :domain, :expire_after, :secure, :httponly 设置相关
Rack::Response#add_cookie 的 cookie 选项
- :skip 不会在响应中设置 cookie,也不会更新会话状态
- :defer 不会在响应中设置 cookie 但仍会更新会话
说明它是否与后端一起使用
- :renew(依赖于实现)会提示生成一个新的
会话 id,以及要在新 id 处引用的数据的迁移。如果
:defer 已设置,它将被覆盖并设置 cookie。
- :sidbits 设置生成会话的长度位数
id 会。
这些选项可以在每个请求的基础上设置,在
env['rack.session.options']。此外,会话的 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