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#out
或 CGI#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,浏览器关闭后失效。 - 设置合理的
expires
或max-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.out
或 cgi.header
设置 Cookie,使用 cgi.cookies
读取客户端 Cookie。Cookies 适合存储小型数据(如用户 ID),但需注意安全性(secure
, httponly
, 转义)和大小限制。CGI 编程简单直接,但现代 Web 开发推荐使用 Rails 等框架替代。
如果你需要更复杂的 Cookie 操作(如多值 Cookie、加密)或有其他问题,请告诉我!