Cookie
一、Cookie的介绍
-
1、
HTTP是无状态协议。简单地说,当你浏览了一个页面,然后转到同一个网站的另一个页 面,服务器无法认识到这是同一个浏览器在访问同一个网站。每一次的访问,都是没有任何关系的。如果我们要实现多个页面之间共享数据的话我们就可以使用Cookie或者Session实 现 -
2、
cookie是存储于访问者的计算机中的变量。可以让我们用同一个浏览器访问同一个域名的时候共享数据。
- Cookie 是一种客户端存储机制,用于在客户端(浏览器)和服务器之间传递信息。在同源策略中,Cookie 也受到了限制。
二、Cookie的特点
cookie保存在浏览器本地- 正常设置的
cookie是不加密的,用户可以自由看到; - 用户可以删除
cookie,或者禁用它 cookie可以被篡改cookie可以用于攻击cookie存储量很小。实际上要被localStorage替代,但是后者 IE9 兼容。
三、Cookie的属性
下面是常用的 Cookie 属性及其含义:
Domain:指定 Cookie 的作用域。只有在指定的域名下才能访问该 Cookie。如果不设置该属性,则默认为当前请求的域名。Path:指定 Cookie 的作用路径。只有在指定的路径下才能访问该 Cookie。如果不设置该属性,则默认为当前请求的路径。Expires:指定 Cookie 的过期时间。该属性的值为一个 GMT 格式的时间字符串,表示该 Cookie 在何时过期。如果不设置该属性,则该 Cookie 会在浏览器关闭后自动删除。Max-Age:指定 Cookie 的过期时间。该属性的值为一个整数,表示该 Cookie 在多少秒后过期。如果设置了Max-Age属性,则会覆盖Expires属性。Secure:指定该 Cookie 只能通过 HTTPS 协议传输。如果不设置该属性,则该 Cookie 可以通过 HTTP 协议和 HTTPS 协议传输。HttpOnly:指定该 Cookie 只能通过 HTTP 协议访问,不能通过 JavaScript 访问。这样可以防止 XSS 攻击窃取 Cookie 的值。SameSite:指定该 Cookie 的 SameSite 属性。SameSite 属性可以有三个值:Strict、Lax和None。Strict表示该 Cookie 只能在同源请求中发送;Lax表示该 Cookie 在跨域情况下只能在 GET 请求中发送,POST 请求需要满足一定条件才能发送;None表示该 Cookie 可以在跨域请求中发送。
这些属性可以通过 Set-Cookie 响应头来设置,例如:
Set-Cookie: name=value; Domain=example.com; Path=/; Max-Age=3600; Secure; HttpOnly; SameSite=Lax
Cookie 与 同源策略
同源策略是浏览器的一项安全功能,它用于限制不同源(域名、协议或端口不同)之间的文档或脚本的交互。同源策略的目的是为了保护用户的隐私和安全。在同源策略中,Cookie 只能在同源(域名、协议或端口相同)之间共享。
这意味着,如果一个网站设置了一个 Cookie,该 Cookie 就只能在该网站的同源网页中访问。其他网站不能访问该 Cookie。例如,如果一个网站的域名是 example.com,它设置了一个 Cookie,该 Cookie 的作用域是 example.com,那么其他域名(例如:test.com)就不能访问该 Cookie。
虽然同源策略对 Cookie 的访问进行了限制,但是可以通过跨域资源共享(CORS)等技术来解决这个问题。CORS 允许服务器控制哪些源可以访问其资源,从而使不同源之间可以共享资源。但是,即使使用了 CORS,Cookie 也必须遵守同源策略的规定。
- 在 HTTP 协议中,Cookie 是通过
Set-Cookie响应头部设置的,它可以包含多个属性,其中就包括Path属性。
Path 属性指定了 Cookie 的作用路径。当客户端发送请求时,如果该请求的 URL 匹配了 Cookie 的作用路径,则该 Cookie 会被发送到服务器端。如果请求的 URL 与 Cookie 的作用路径不匹配,则浏览器不会发送该 Cookie。
例如,如果某个网站设置了一个 Cookie,它的 Path 属性为 /foo,则该 Cookie 只会在请求路径为 /foo 或者 /foo/xxx 的页面中发送到服务器端,而不会在其他路径下发送。这样可以限制 Cookie 只在特定的路径中使用,提高了 Cookie 的安全性。
需要注意的是,Path 属性是以一个 URL 路径作为 Cookie 的作用范围,而不是以一个域名为作用范围。也就是说,如果一个网站在不同的路径下设置了相同名称的 Cookie,它们是相互独立的,不会相互干扰。同时,如果一个 Cookie 的 Path 属性设置为 /,则该 Cookie 可以在整个网站中使用。
因此,Path 属性是 Cookie 的一个重要属性,可以限制 Cookie 的作用范围,提高 Cookie 的安全性和可靠性。
在Nestjs中使用Cookie
-
2、下载
npm install cookie-parser npm install @types/cookie-parser -D
cookic-parser的参数说明
| NO. | 参数 | 类型 | 参数说明 |
|---|---|---|---|
| 1 | domain | String | 指定域名下有效 |
| 2 | expires | Date | 过期时间(秒),设置在某个时间点后会在该cookoe后失效 |
| 3 | httpOnly | Boolean | 默认为false表示不允许客户端(通过js来获取cookie) |
| 4 | maxAge | String | 最大失效时间(毫秒),设置在多少时间后失效 |
| 5 | path | String | 表示cookie影响到的路径,如:path=/如果路径不能匹配的时候,浏览器则不发送这个cookie |
| 6 | secure | Boolean | 当 secure 值为true 时,cookie 在 HTTP 中是无效,在 HTTPS中才有效 |
| 7 | signed | Boolean | 表示是否签名cookie,如果设置为true的时候表示对这个cookie签名了,这样就需要用res.signedCookies()获取值cookie不是使用res.cookies()了 |
如果要销毁cookie常见的方式
-
直接将值设置为空
-
设置
maxAge=0 -
3、在
main.ts中使用// 导包 import * as cookieParser from 'cookie-parser'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 使用 app.use(cookieParser()); await app.listen(3000); } bootstrap(); -
4、在组件的控制器中写入和获取
cookieimport { Controller, Get, Response, Request } from '@nestjs/common'; @Controller('user') export class UserController { @Get() index(@Request() req) { console.log(req.cookies.name, '当前的cookie'); return '主页'; } @Get('login') login(@Response() res) { // 如果使使用了res就不能使用return,必须使用send res.cookie('name', 'hello', { maxAge: 1000 * 5, httpOnly: true }); res.send('登录页面'); } } -
5、在浏览器控制图查看
cookie到了时间刷新浏览器控制图上的刷新的,
cookie就会被清空的
Nestjs中使用session
-
1、
session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而session保存 在服务器上 -
2、
session的工作流程
当浏览器访问服务器并发送第一次请求的时候,服务器端会创建一个session对象,生成一个类似于{key: '', value: ''}的对象,然后将key(cookie)返回到浏览器(客户)端,浏览器再次访问的时候携带这个key(cookie)到服务器端,找到这个session的value值。 -
3、在
nestjs中使用express-session进行session的操作npm install express-session npm install @types/express-session -D -
4、在
main.ts中配置sessionimport { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import * as session from 'express-session'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 配置中间件使用session,加盐是123456(随便写的) app.use(session({ secret: '123456', cookie: { maxAge: 60000 } })) await app.listen(3000); } bootstrap();使用
app.use(session({ secret: '123456', cookie: { maxAge: 60000 } }))开启了表示服务器开启了session 当浏览器第一次请求的时候服务器会响应一个cookie用来作为此次连接的凭证,以后每次请求浏览器都会带着这个凭证,这样服务器就能识别浏览器了,相当于php里面的session_start()
Cookie: connect.sid=s%3AFK-7NF03A6PGM85rQQ8ixAZarIe_hsGI.JIizzuGr%2BYljCwghdWn02U5PODapnIThVeF1m%2BnWUCY
-
5、创建
user的模块及控制器(忽视请求方式,只是方便浏览器模拟请求)import { Controller, Get, Request, Response } from '@nestjs/common'; @Controller('user') export class UserController { @Get() index( @Request() req: { [key: string]: any } ): string { console.log(req.session); return '用户主页'; } @Get('login') login( @Response() res: { [key: string]: any }, @Request() req: { [key: string]: any } ): void { req.session.name = 'hello'; // 再次提醒使用了@Response就不能使用return res.send('登录页面') } } -
6、先在浏览器中访问
localhost:3000/user/login然后访问localhost:3000/user// 编辑器控制图打印出信息,可以获取到刚刚设置的session Session { cookie: { path: '/', _expires: 2020-07-27T09:28:20.046Z, originalMaxAge: 60000, httpOnly: true }, name: 'hello' } -
7、常见参数的说明
| NO | 参数 | 说明 |
|---|---|---|
| 1 | secret | 一个 String 类型的字符串,作为服务器端生成session 的签名 |
| 2 | name | 返回客户端的key 的名称,默认为connect.sid,也可以自己设置 |
| 3 | resave | 强制保存 session即使它并没有变化,。默认为true。建议设置成 false |
| 4 | saveUninitalized | 强制将未初始化的 session 存储。当新建了一个 session 且未设定属性或值时,它就处于 未初始化状态。在设定一个 cookie 前,这对于登陆验证,减轻服务端存储压力,权限控制是有帮助的。( 默认:true)。建议手动添加 |
| 5 | cookie | 设置返回到前端key 的属性,默认值为{ path: ‘/’, httpOnly: true, secure: false, maxAge: null }。 |
| 6 | rolling | 在每次请求时强行设置 cookie,这将重置cookie 过期时间(默认:false) |
-
8、
session的销毁 -
设置
maxAge=0req.session.cookie.maxAge=0 -
将值设置为空
-
使用
destroy销毁方法req.session.destroy((err) => { ... })