cookie 简介
网页的 Cookie 是一种由网站创建并保存在用户计算机上的小型数据文件,用于追踪和记住用户的信息和行为。
当用户访问一个网站时,网站的服务器可能会发送一个或多个 Cookie 到用户的浏览器,浏览器会将这些信息存储起来。
以后,当用户再次访问同一个网站时,浏览器会把这些信息发送回服务器,这样网站就可以识别用户并根据用户的以前的行为来定制内容。
Cookie 通常包含以下信息:
- 名称:一个独特的标识符,用来识别 Cookie。
- 值:存储在 Cookie 中的数据(通常是加密的)。
- 到期时间:Cookie 的有效期限。过期后,Cookie 会自动删除。
- 路径:Cookie 适用的网站路径。默认情况下,Cookie 只对设置它的网页有效。
- 域:Cookie 适用的域名。默认情况下,只有创建 Cookie 的网站可以读取它。
- 安全标志:指示 Cookie 是否仅通过加密的 HTTPS 连接发送。
Cookie 主要用途包括:
- 会话管理:保存用户的登录信息、购物车内容、游戏分数或其他需要跟踪的数据。
- 个性化:记录用户的偏好设置,如网站主题、语言选择或配置。
- 追踪:记录和分析用户的行为,以便网站运营商可以改进网站的用户体验或进行广告定位。
Nest 中使用 Cookie
- 安装必要的中间件 :安装
cookie-parser
:
bash
npm install cookie-parser
- 导入中间件 :主模块中导入并配置
cookie-parser
。
typescript
import * as cookieParser from 'cookie-parser';
// 在 AppModule 的 imports 数组中添加
@Module({
// ...
imports: [
// ...
],
// ...
})
export class AppModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(cookieParser())
.forRoutes('*'); // 应用于所有的路由
}
}
也可以在 main.ts 这样配置:
- 设置读取 Cookie :可以在控制器中使用
@Res()
装饰器来访问底层的 Response 对象,并设置 Cookie。 若要读取请求中的 Cookie,可以使用@Req()
装饰器来获取请求对象,并从中读取 Cookie。
- 访问测试
注意,当设置 Cookie 时,可以传递一个选项对象来指定 Cookie 的属性,比如 expires
、httpOnly
、secure
等,以增加安全性和控制 Cookie 的行为。
在生产环境中,建议设置 httpOnly
(只允许服务器访问此 cookie) 和 secure
(只会在 https 环境才会发送此 cookie 到服务器)选项,以减少 XSS 和 Cookie 拦截的风险。
Nest 中 Cookie 参数
上面我们只设置了 httpOnly 选项:
其实还有很多选项:
当使用 response.cookie(name, value, [options])
方法设置 Cookie 时,可以通过 options
对象来指定多种属性,以控制 Cookie 的行为。以下是一些常见的选项参数:
maxAge
:指定 Cookie 的最大存活时间(以毫秒为单位)。这会设置 Cookie 的Expires
属性为当前时间加上maxAge
的值。
typescript
{ maxAge: 1000 * 60 * 60 * 24 } // Cookie 将在 24 小时后过期
expires
:指定一个Date
对象,即 Cookie 的到期时间。如果未设置或设置为0
,则创建一个会话 Cookie。
typescript
{ expires: new Date(Date.now() + 1000 * 60 * 60 * 24) } // 同样设置为 24 小时后过期
httpOnly
:设置为true
时,Cookie 仅通过 HTTP(S) 协议传输,无法通过客户端脚本(如 JavaScript)访问。这有助于防止跨站脚本攻击(XSS)。
typescript
{ httpOnly: true }
secure
:设置为true
时,Cookie 仅在 HTTPS 连接上发送。在开发环境中,通常设置为false
。
typescript
{ secure: true }
domain
:指定 Cookie 的域,只有来自该域的请求才会包含该 Cookie。
typescript
{ domain: 'example.com' }
path
:指定 Cookie 的路径,只有请求该路径或其子路径的请求才会包含该 Cookie。
typescript
{ path: '/' } // 对整个网站有效
**sameSite**
:这是一个用于防止 CSRF 攻击和用户追踪的安全性设置,它可以有以下值:
'strict'
:Cookie 仅在请求来自同一网站时发送。'lax'
:在一些第三方请求中发送,例如用户从另一个网站通过链接访问。'none'
:即使是在跨站请求中也会发送 Cookie,但此时必须设置secure
为true
。
typescript
{ sameSite: 'lax' }
signed
:如果设置为true
,Cookie 会被签名,这可以防止客户端篡改 Cookie 的值。为了使用签名功能,你需要设置一个签名密钥。
typescript
{ signed: true }
这些选项可以根据应用需求进行组合使用,以确保 Cookie 的安全性和正确的行为。
例如,对于需要保护的 Cookie(如认证令牌),可能会同时设置 httpOnly
、secure
、sameSite
和 maxAge
或 expires
选项。
删除 Cookie 只需要设置 maxAge:0 选项即可。
Nest 中 Cookie 加密
之前我们的 cookie 都是明文存储的,浏览器控制台可以看见:
我们需要配置 cookie 加密:
- 配置中间件的时候需要传参:
- 设置 cookie 的时候配置 signed 属性:
访问下页面重新设置 cookie:
存储后的值已经变成加密后的了:
注意现在代码里面获取 cookie 要这样写:
访问下页面:
成功获取到了我们设置的值。
最后我们也可以使用 cookie-session 或者 express-session 等第三方包配合 cookie-parser 来创建加密的 cookie。