目录
建议在本博文之前,先浏览一遍 Cookie与前端安全_二阶求导的博客-CSDN博客。
一、session
1. 介绍
session代表服务器和浏览器的一次会话过程,这个过程可以是连续的、也可以是断断续续的。session对象用来在服务端存储用户会话的一些信息,保存在服务器的内存、缓存、硬盘等。
2. 工作原理
大多系统也是根据此原理来验证用户登录状态(session和cookie结合)。cookie的验证流程也如下,因为大多系统都根据此原理来验证的。
1. 当用户访问到一个服务器,登录验证成功后,如果服务器启用了session,那么服务器就要为该用户创建一个session。
2. 在创建这个session的时候,服务器首先会检查这个用户发来的请求里是否包含了一个session id。如果包含,则说明之前该用户已经登陆过并为此用户创建过session,那服务器就按照这个session id把对应的session在服务器的内存中查找出来(如果查找不到,就有可能为他新创建一个),如果请求里不包含,则说明之前用户没有登录或登录失效,那就为该用户创建一个session并生成相关的session id。(session id是唯一的、不重复的字符串)
3. 这个session id将被在本次响应中返回到客户端保存(Set-Cookie字段中保存),而保存这个session id的正是cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
4. 后续登录时,请求就会携带session id的cookie给服务端,由此得知用户的身份。
3. 作用
session的作用就是在服务端存储用户和服务器会话的一些信息。典型的应用有:
- 判断用户是否登录
- 购物车功能
二、token
1. 介绍
token是验证用户身份所需的一份凭证。基于token的用户认证是一种服务端无状态的认证方式,服务端不用存放token数据。用解析token的时间换取session的存储空间。
2. 工作过程
1. 用户请求登录,服务器验证用户名和密码。
2. 验证成功后,服务器生成一个token(一般是JWT形式)给客户端,存储在本地(cookie或localStorage)中 。
3. 客户端后续的请求中,都会在请求头中添加token一起发送给服务器。
4. 服务器进行解析校验,成功则返回响应。
三、session\cookie\token
1. session与cookie区别
cookie只是实现session的一种方案,大多采用cookie+session的方式。
cookie | session | |
存储位置 | 客户端 | 服务端 |
有效期 | 可以永久保存 | 与当前标签页生命周期相同 |
安全性 | cookie存储在客户端,可能会被窥探。像密码最好加密。 | 更安全。 |
性能 | 并发用户很多时,适合用cookie。 | 当并发访问的用户很多,服务器需要为每个用户生成session,耗费大量内存。 |
2. session与token区别
token | session | |
服务端无状态 | 使服务端无状态化,不会存储会话信息。 | 使服务端有状态,记录会话信息。 |
安全性 | token更安全,每个请求都要签名,能防止csrf攻击。 | 只提供了session id这种简单的认证。 |
作用 | 一般用于身份验证(加密身份证,只要出示就知道是自己人) | 一般用于标识会话(身份证,每次都要根据id去查一下) |
存储位置 | 客户端 | 服务器 |
3. session与JWT的区别
4. cookie、session、token的区别,优劣
cookie | session | token | |
存储位置 | 客户端 | 服务端 | 客户端 |
安全性 | 最差 | 中间 | 最好 |
服务端有状态 | 有 | 有 | 无 |
(1)cookie
优点:
缺点:会被附加到每个http请求,增加了流量;大小为4KB,对于负责的存储需求来说是不够用的;在http请求中的cookie是明文传输的,不够安全,不要存储敏感信息(除非用https)。
(2)session
优点:
缺点:如果服务器做了负载均衡,那么到另一台服务器上后,session会丢失。
(3)token
优点:可以避开同源策略,可以避免csrf攻击,无状态所以多个服务器可共享。
缺点:后端控制不了token,不能设置将它作废。
四、登录功能
1. cookie + session方式
这种模式适用于单机,当服务器集群时,就会要求session共享。因此采用JWT方案,让服务器不保存session了,所有数据都保存在客户端,每次请求都发回服务器。
2. token登录(JWT)
服务器认证后,生成一个Json对象,发回给用户,以后用户与服务器通信时,都要发回这个Json对象。为了防止用户篡改数据,服务器生成该对象时会加上签名。
Header.Payload.Signature
JWT的3个部分如上。
(1)头部Header
{
"alg": "HS256", // 签名的算法,默认HS256
"typ": "JWT" // token的类型
}
//最后再用过Base64URL算法转成字符串
(2)负载Payload
1.也是一个JSON对象
2.里面有过期时间、生效时间等
3.也要使用BaseURL算法转成字符串
(3)签名Signature
对前两部分进行签名,防止数据篡改。
首先需要指定一个密钥,这个密钥只有服务器才知道、不能泄漏给用户。然后,使用Header中指定的签名算法,对【base64URL(header)+base64URL(payload)+密钥】产生签名。
然后,把这三部分拼成一个字符串,用点号分隔,返回给用户。