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