Ruby 使用Sinatra会话和;机架::会话::EncryptedCookie

Ruby 使用Sinatra会话和;机架::会话::EncryptedCookie,ruby,cookies,sinatra,session-cookies,rack,Ruby,Cookies,Sinatra,Session Cookies,Rack,我正在学习Sinatra框架&开发一个登录系统。我发现了两种使用饼干的方法 简单的Sinatra内置方式: enable :sessions set :session_secret, 'random-key' 此方法在登录时生成以下cookie内容(用于会话。检查以获取输出): 另一种方法是使用加密cookie: require 'sinatra' require 'encrypted_cookie' use Rack::Session::EncryptedCookie, :secret =

我正在学习Sinatra框架&开发一个登录系统。我发现了两种使用饼干的方法

简单的Sinatra内置方式:

enable :sessions
set :session_secret, 'random-key'
此方法在登录时生成以下cookie内容(用于
会话。检查
以获取输出):

另一种方法是使用加密cookie:

require 'sinatra'
require 'encrypted_cookie'

use Rack::Session::EncryptedCookie, :secret => "random-key"
但这种方法在登录时会生成以下cookie内容(使用
会话。此处也要检查):

为什么
enable:sessions
要用所有这些信息创建一个如此大的cookie&为什么需要它(特别是那些HTTP\u…部分?),因为
Rack::Session::EncryptedCookie
没有生成任何信息

您是否认为使用
enable:sessions
应该是首选,因为它具有csrf令牌和会话id?或者您认为既然它是加密的,那么
Rack::Session::EncryptedCookie
就足够了吗

我安装了以下版本的gems:

encrypted_cookie (0.0.4)
rack (1.5.2)
rack_csrf (2.4.0)
sinatra (1.4.3)
thin (1.5.1)

如果您需要更多信息,请告诉我…

,因为
Rack::Session::EncryptedCookie
要求您的密码长度至少为16位。在自述文件中,他们建议使用OpenSSL生成机密,如下所示:

ruby -ropenssl -e "puts OpenSSL::Random.random_bytes(16).inspect"
如果打开inspector,您将看到一个名为“rack.session”的cookie,其内容被混淆。

因为当您启用
:sessions
时,Sinatra将使用中间件。它使饼干更大,但更安全

相关片段:

def setup_default_middleware(builder)
  builder.use ExtendedRack
  builder.use ShowExceptions       if show_exceptions?
  builder.use Rack::MethodOverride if method_override?
  builder.use Rack::Head
  setup_logging    builder
  setup_sessions   builder
  setup_protection builder
end

def setup_sessions(builder)
  return unless sessions?
  options = {}
  options[:secret] = session_secret if session_secret?
  options.merge! sessions.to_hash if sessions.respond_to? :to_hash
  builder.use session_store, options
end

def setup_protection(builder)
  return unless protection?
  options = Hash === protection ? protection.dup : {}
  options = {
    img_src:  "'self' data:",
    font_src: "'self'"
  }.merge options

  protect_session = options.fetch(:session) { sessions? }
  options[:without_session] = !protect_session

  options[:reaction] ||= :drop_session

  builder.use Rack::Protection, options
end
  • sessions?
    如果启用:sessions,则返回true
  • session\u存储
    默认为
    Rack::session::Cookie
Rack::Session::EncryptedCookie

也就是说,如果要将
机架::会话::EncryptedCookie
机架生产
一起使用,可以通过以下方式轻松完成:

enable :sessions
set :session_store, Rack::Session::EncryptedCookie
仅供参考,由于缺少一些功能(秘密旋转、自定义序列化程序等),并且不再需要维护,我决定更换它


希望有帮助。

据我所知,在Sinatra中使用Rack::Session::Cookie并将Session\u secret作为环境变量写入时,创建的会话在项目部署后不会被破坏。我认为这在单页应用程序中是一个风险。

是的。我知道:)。但我的问题是,您是否更喜欢
enable:sessions
,因为它正在生成会话id和csrf令牌&所有这些额外的东西?或者您更喜欢
Rack::Session::EncryptedCookie
,因为它是加密的&不需要添加这些内容?您是否使用其他中间件?执行
enable:sessions
,然后检查会话,会得到与
Rack::session::EncryptedCookie
类似的输出。就我个人而言,我使用
Rack::Session::Cookie
作为中间件,并在其上设置秘密(从环境变量加载)。Hmmm。在使用
enable:sessions
方法时,我没有使用任何其他中间件。顺便说一句,我编辑了这个问题,以包括所需gems的版本。和你相比,我可能有不同版本的宝石。有什么线索吗?
def setup_default_middleware(builder)
  builder.use ExtendedRack
  builder.use ShowExceptions       if show_exceptions?
  builder.use Rack::MethodOverride if method_override?
  builder.use Rack::Head
  setup_logging    builder
  setup_sessions   builder
  setup_protection builder
end

def setup_sessions(builder)
  return unless sessions?
  options = {}
  options[:secret] = session_secret if session_secret?
  options.merge! sessions.to_hash if sessions.respond_to? :to_hash
  builder.use session_store, options
end

def setup_protection(builder)
  return unless protection?
  options = Hash === protection ? protection.dup : {}
  options = {
    img_src:  "'self' data:",
    font_src: "'self'"
  }.merge options

  protect_session = options.fetch(:session) { sessions? }
  options[:without_session] = !protect_session

  options[:reaction] ||= :drop_session

  builder.use Rack::Protection, options
end
enable :sessions
set :session_store, Rack::Session::EncryptedCookie