Ruby CGI Cookie

在 Ruby 的 CGI(Common Gateway Interface) 编程中,Cookie 是一种用于在客户端(浏览器)和服务器之间存储和传递小型数据的机制,常用于会话管理、用户身份验证或保存用户偏好。Ruby 的 cgi 库提供了 CGI::Cookie 类来创建、设置和读取 Cookies。以下是对 Ruby CGI 中 Cookie 使用的中文讲解,涵盖核心方法、创建与读取 Cookies、示例代码及注意事项,力求简洁清晰,并避免重复之前的内容(如 CGI 编程概述)。


1. Cookie 简介

Cookies 是存储在浏览器中的键值对,由服务器通过 HTTP 响应发送,浏览器在后续请求中自动回传。Ruby 的 CGI 模块通过 CGI::Cookie 类管理 Cookies,支持设置属性(如过期时间、路径)并解析客户端发送的 Cookies。

用途

  • 保存用户会话信息(如用户 ID)。
  • 跟踪用户行为或偏好。
  • 实现简单的状态管理。

2. CGI::Cookie 类

CGI::Cookie 用于创建和操作 Cookie 对象,常用属性包括:

  • name:Cookie 的名称(必需)。
  • value:Cookie 的值(字符串或字符串数组)。
  • expires:过期时间(Time 对象)。
  • path:Cookie 有效的路径(如 / 表示整个站点)。
  • domain:Cookie 有效的域名。
  • secure:布尔值,仅 HTTPS 连接可用(默认 false)。
  • httponly:布尔值,禁止 JavaScript 访问 Cookie(默认 false)。

创建 Cookie

require 'cgi'

cookie = CGI::Cookie.new(
  'name' => 'user_id',
  'value' => '12345',
  'expires' => Time.now + 3600,  # 1 小时后过期
  'path' => '/',
  'secure' => true,
  'httponly' => true
)

3. 设置 Cookie

Cookies 通过 CGI#outCGI#header 方法在 HTTP 响应头中设置。

使用 cgi.out

#!/usr/bin/ruby
require 'cgi'

cgi = CGI.new
cookie = CGI::Cookie.new('name' => 'user_id', 'value' => '12345', 'expires' => Time.now + 3600)
cgi.out('cookie' => [cookie]) do
  "<html><body><p>Cookie set for user_id: 12345</p></body></html>"
end

说明

  • cookie 选项接受单个 CGI::Cookie 或 Cookie 数组。
  • 浏览器接收后存储 Cookie,后续请求会自动携带。

使用 cgi.header

#!/usr/bin/ruby
require 'cgi'

cgi = CGI.new
cookie = CGI::Cookie.new('name' => 'session', 'value' => 'abc123')
puts cgi.header('cookie' => [cookie])
puts "<html><body><p>Cookie set!</p></body></html>"

4. 读取 Cookie

客户端发送的 Cookies 存储在 cgi.cookies 中,返回一个哈希,键为 Cookie 名称,值为 CGI::Cookie 对象数组。

示例

#!/usr/bin/ruby
require 'cgi'

cgi = CGI.new
user_id = cgi.cookies['user_id'][0]&.value || 'Guest'
cgi.out do
  "<html><body><p>Welcome, User ID: #{CGI.escapeHTML(user_id)}</p></body></html>"
end

说明

  • cgi.cookies['user_id'] 返回 Cookie 数组,[0].value 获取第一个值。
  • 使用 CGI.escapeHTML 转义,防止 XSS 攻击。
  • &.value 避免空 Cookie 导致的错误。

5. 更新与删除 Cookie

  • 更新 Cookie:设置相同名称的新 Cookie,覆盖旧值。
  cookie = CGI::Cookie.new('name' => 'user_id', 'value' => '67890')
  cgi.out('cookie' => [cookie]) { "<p>Cookie updated!</p>" }
  • 删除 Cookie:设置过期时间为过去。
  cookie = CGI::Cookie.new('name' => 'user_id', 'value' => '', 'expires' => Time.now - 3600)
  cgi.out('cookie' => [cookie]) { "<p>Cookie deleted!</p>" }

6. 综合示例

以下示例实现一个简单的 CGI 脚本,通过 Cookie 记录用户最后访问的用户名,并显示欢迎消息。

#!/usr/bin/ruby
require 'cgi'

cgi = CGI.new
name = cgi['name'] || 'Guest'
cookie = CGI::Cookie.new(
  'name' => 'last_user',
  'value' => name,
  'expires' => Time.now + 86400,  # 1 天
  'path' => '/'
)

begin
  last_user = cgi.cookies['last_user'][0]&.value || 'None'
  cgi.out('cookie' => [cookie]) do
    cgi.html do
      cgi.body do
        cgi.h1 { "Welcome, #{CGI.escapeHTML(name)}!" } +
        cgi.form('action' => '/cgi-bin/cookie.rb', 'method' => 'post') do
          cgi.p { "Name: " + cgi.text_field('name') } +
          cgi.submit('Submit')
        end +
        cgi.p { "Last user: #{CGI.escapeHTML(last_user)}" }
      end
    end
  end
rescue => e
  cgi.out('status' => '400') { "<html><body><p>Error: #{CGI.escapeHTML(e.message)}</p></body></html>" }
end

保存:保存为 /usr/lib/cgi-bin/cookie.rb,设置权限(chmod +x)。
访问http://localhost/cgi-bin/cookie.rb?name=Alice
功能

  • 显示欢迎消息和输入表单。
  • 通过 Cookie 保存上一个用户名。
  • 使用 CGI.escapeHTML 防止 XSS。

7. 注意事项

  • 安全性
  • 使用 secure: true 确保 Cookie 仅在 HTTPS 传输。
  • 使用 httponly: true 防止 JavaScript 访问 Cookie。
  • 转义 Cookie 值(CGI.escapeHTML)防止 XSS。
  • 不要存储敏感信息(如密码)在 Cookie 中。
  • 过期时间
  • 未设置 expires 的 Cookie 为会话 Cookie,浏览器关闭后失效。
  • 设置合理的 expiresmax-age 控制 Cookie 寿命。
  • 路径与域名
  • path: '/' 使 Cookie 在整个站点有效。
  • domain 设置需匹配服务器域名,否则 Cookie 无效。
  • 大小限制:浏览器通常限制 Cookie 大小(约 4KB),避免存储过多数据。
  • 调试:检查浏览器开发者工具或服务器日志(如 /var/log/apache2/access.log)。
  • 现代替代:Rails/Sinatra 使用更高级的会话管理(如 session),性能和安全性更优。

8. 总结

Ruby 的 CGI::Cookie 类通过 name, value, expires 等属性管理 Cookies,结合 cgi.outcgi.header 设置 Cookie,使用 cgi.cookies 读取客户端 Cookie。Cookies 适合存储小型数据(如用户 ID),但需注意安全性(secure, httponly, 转义)和大小限制。CGI 编程简单直接,但现代 Web 开发推荐使用 Rails 等框架替代。

如果你需要更复杂的 Cookie 操作(如多值 Cookie、加密)或有其他问题,请告诉我!

文章已创建 3123

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部