5

我正在学习 Sinatra 框架并开发登录系统。我遇到了两种使用 cookie 的方法。

一个简单的 Sinatra 内置方式:

enable :sessions
set :session_secret, 'random-key'

这种方法在登录时会产生以下 cookie 内容(用于session.inspect获取输出):

{"session_id"=>"6be0b9a31831604ba51114d265ba952482e0b2da6ced6c54e15ebe7f212858ca", 
"tracking"=>{"HTTP_USER_AGENT"=>"b8c1e8f89eeaea0b825bed0d811f0c7678e98c74", 
"HTTP_ACCEPT_ENCODING"=>"a0bfc876d68fe7aea700da5ea8925abac6f2f794", 
"HTTP_ACCEPT_LANGUAGE"=>"dd065ed263c67d799f943ab6c39b55c5e008cbb5"}, 
"csrf"=>"b480324f510e4f391d15cee8236a8fb74a5aaa5ce2f9ad38e4dbb025a823b16e",    
"name"=>"john"}

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

require 'sinatra'
require 'encrypted_cookie'

use Rack::Session::EncryptedCookie, :secret => "random-key"

但是这种方法在登录时会产生以下 cookie 内容(session.inspect也在这里使用):

{:name=>"john"}

为什么要enable :sessions使用所有这些信息创建如此大的 cookie 以及为什么需要它(尤其是那些 HTTP_... 部分?)因为Rack::Session::EncryptedCookie没有生成任何信息。

您是否认为 usingenable :sessions应该是首选,因为它具有 csrf 令牌和会话 ID?或者你认为Rack::Session::EncryptedCookie它是加密的就足够了吗?

我安装了以下版本的 gem:

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

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

4

3 回答 3

1

因为当你启用 Sinatra 时会使用rack-protection中间件:sessions。它使 cookie 更大但更安全。

相关片段:

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_storeRack::Session::Cookie默认情况下

和...之间的不同Rack::Session::EncryptedCookie

也就是说,如果您想使用Rack::Session::EncryptedCookiewith rack-production,可以通过以下方式轻松完成:

enable :sessions
set :session_store, Rack::Session::EncryptedCookie

仅供参考,由于encrypted_cookie缺少某些功能(秘密轮换、自定义序列化程序等)并且不再处于维护状态,因此我制作了另一个来替换它。

希望能帮助到你。

于 2016-12-05T20:23:41.270 回答
0

因为Rack::Session::EncryptedCookie要求您的秘密至少有 16 位长。在 README 中,他们建议使用 OpenSSL 生成密钥,如下所示:

ruby -ropenssl -e "puts OpenSSL::Random.random_bytes(16).inspect"

如果你打开你的检查器,你会看到一个名为“rack.session”的cookie,它的内容被混淆了。

于 2013-06-28T17:47:07.633 回答
0

据我所知,在 Sinatra 中使用 Rack::Session::Cookie 并将 session_secret 写入环境变量时,已创建的会话在项目部署后不会销毁。我认为这是单页应用程序的风险。

于 2017-07-16T01:35:19.483 回答