class CGI::Session

概述

此文件提供了 CGI::Session 类,该类为 CGI 脚本提供会话支持。会话是一系列 HTTP 请求和响应,它们链接在一起并与单个客户端关联。与会话关联的信息在请求之间存储在服务器上。会话 ID 在客户端和服务器之间透明地传递,对用户来说是透明的。这为原本无状态的 HTTP 请求/响应协议添加了状态信息。

生命周期

CGI 对象创建一个 CGI::Session 实例。默认情况下,如果没有会话存在,此 CGI::Session 实例将启动一个新会话,如果存在,则继续此客户端的当前会话。new_session 选项可用于始终或从不创建新会话。有关更多详细信息,请参见 new()。

delete() 从会话存储中删除会话。但是,它不会从客户端删除会话 ID。如果客户端使用相同的 ID 发出另一个请求,则效果是使用旧会话的 ID 启动一个新会话。

设置和检索会话数据。

Session 类将数据与会话关联为键值对。可以使用 ‘[]’ 索引 Session 实例来设置和检索此数据,就像哈希一样(尽管不支持其他哈希方法)。

当请求的会话处理完成后,应使用 close() 方法关闭会话。这将把会话的状态存储到持久存储中。如果您想在不完成此请求的会话处理的情况下将该会话的状态存储到持久存储中,请调用 update() 方法。

存储会话状态

调用者可以使用 CGI::Session::newdatabase_manager 选项来指定用于会话数据的存储形式。以下存储类作为标准库的一部分提供

CGI::Session::FileStore

将数据以纯文本形式存储在平面文件中。仅适用于 String 数据。这是默认存储类型。

CGI::Session::MemoryStore

将数据存储在内存哈希中。数据仅在当前 Ruby 解释器实例运行时保持存在。

CGI::Session::PStore

以 Marshalled 格式存储数据。由 cgi/session/pstore.rb 提供。支持任何类型的数据,并提供文件锁定和事务支持。

还可以通过定义具有以下方法的类来创建自定义存储类型

new(session, options)
restore  # returns hash of session data.
update
close
delete

会话中间更改存储类型不起作用。特别要注意的是,默认情况下,FileStorePStore 会话数据文件具有相同的名称。如果您的应用程序从一个切换到另一个,而没有确保文件名将不同,并且客户端仍然在 cookie 中保存着旧会话,那么事情将会变得很糟糕!

维护会话 ID。

大多数会话状态都保存在服务器上。但是,会话 ID 必须在客户端和服务器之间来回传递,以维护对此会话状态的引用。

最简单的方法是通过 cookie。如果客户端启用了 cookie,CGI::Session 类会透明地支持通过 cookie 进行会话 ID 通信。

如果客户端禁用了 cookie,则必须将会话 ID 作为客户端发送到服务器的所有请求的参数包含在内。CGI::Session 类与 CGI 类结合使用,会将该会话 ID 透明地添加到所有使用 CGI#form() HTML 生成方法生成的表单的隐藏输入字段中。不为其他机制(如 URL 重写)提供内置支持。调用者负责从 session_id 属性中提取会话 ID,并将其手动编码到 URL 中,并将其作为隐藏输入添加到由其他机制创建的 HTML 表单中。此外,会话过期不会自动处理。

使用示例

设置用户的姓名

require 'cgi'
require 'cgi/session'
require 'cgi/session/pstore'     # provides CGI::Session::PStore

cgi = CGI.new("html4")

session = CGI::Session.new(cgi,
    'database_manager' => CGI::Session::PStore,  # use PStore
    'session_key' => '_rb_sess_id',              # custom session key
    'session_expires' => Time.now + 30 * 60,     # 30 minute timeout
    'prefix' => 'pstore_sid_')                   # PStore option
if cgi.has_key?('user_name') and cgi['user_name'] != ''
    # coerce to String: cgi[] returns the
    # string-like CGI::QueryExtension::Value
    session['user_name'] = cgi['user_name'].to_s
elsif !session['user_name']
    session['user_name'] = "guest"
end
session.close

安全地创建新会话

require 'cgi'
require 'cgi/session'

cgi = CGI.new("html4")

# We make sure to delete an old session if one exists,
# not just to free resources, but to prevent the session
# from being maliciously hijacked later on.
begin
    session = CGI::Session.new(cgi, 'new_session' => false)
    session.delete
rescue ArgumentError  # if no old session
end
session = CGI::Session.new(cgi, 'new_session' => true)
session.close