## 一,Token
**token特点**
Token 临时且唯一 保证不能够重复 (缓存有效期机制),智能门锁、临时密码 具有有效期2小时
**token生成**
Token如何生成:uuid作为token。
比如:生成token(uuid生成),作为Rediskey放入redis中,Redis的key作为有效期。
实际项目中,token和sessionid非常相似
**session缺陷**
传统项目使用session存在缺陷:放入到服务端,
session 类似redis存放缓存内容,
session中的sessionid类似于token,
session共享效率低
大的项目都是基于token替代session,Redis中。
**token的使用**
每次请求的时候在请求头中传递该token,服务器端接收到
Token,从Redis查找对应key对应的value userid。
再根据userid查询用户信息返回给客户端。
使用token的情况下依赖:必须依赖服务器端redis。
Token:
1)临时且唯一。
2)能够隐藏参数的真实性。
## 二,JWT
jwt和token的设计思想基本一致。
JWT:json web token
Json:数据交换格式 轻量级、跨语言、减少带宽、可读性高
**加密算法**
- 单向加密(不可逆加密,不能反解):MD5、SHA
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20210706140528839.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTY5NjQz,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20210706140542834.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTY5NjQz,size_16,color_FFFFFF,t_70)
优点:性能好,加密或解密只需要遍历一次
- 双向加密(可逆加密,需要的时候可以反解为明文) :对称加密(对称加密过程和解密过程使用的同一个密钥) aes des 非对称加密(使用公钥进行加密,使用私钥进行解密。) rsa
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20210706140731451.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTY5NjQz,size_16,color_FFFFFF,t_70)
根据一个数学原理会生成一对密钥,一个叫公钥、一个叫私钥,同一份文档用公钥加密了就只能用私钥解密。
缺点:有点复杂,所以机密解密性能不好
主要两个应用场景:
1)加密传输:公钥加密,拥有私钥的可以解密。
2)身份验证:使用私钥进行加密,因为公钥是公开的,理论上所有人都知道,他们通过此来对这个人进行身份验证
**JWT主要分成 三个部分组成**
第一部分:header头部 ,标记使用什么算法 HS256,RSA256.
第二部分:PayLoad(载荷),jwt存放的数据,注意不能够存放敏感数据(userid、号码)
第三部分:sign,PayLoad采用MD5加密之后的签名值
**Jwt生成:
Base64.ENcode(header).Base64.ENcode(PayLoad).签名值**
**手写JWT**
```yaml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.72</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
```
```java
package com.shuang;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import java.util.Base64;
public class test1 {
private static String SIGN_KEY="shuang";
public static void main(String[] args) {
//head
JSONObject header =new JSONObject();
header.put("alg","HS256");
//payload
JSONObject payload=new JSONObject();
payload.put("phone","12345678901");
//sign
String sign= DigestUtils.md5Hex(payload+SIGN_KEY);
String jwt= Base64.getEncoder().encodeToString(header.toJSONString().getBytes())
+"."+Base64.getEncoder().encodeToString(payload.toJSONString().getBytes())
+"."+sign;
System.out.println(jwt);
//解密
String[] split=jwt.split("\\.");
String payLoad=new String(Base64.getDecoder().decode(split[1].getBytes()));
System.out.println(DigestUtils.md5Hex(payLoad+SIGN_KEY).equals(sign));
System.out.println(payLoad);
}
}
```
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20200728055829256.png)
Base64不属于对称加密属于编码器。
**Jwt与token的区别**
1)token对应的内容存放在Redis中
2)Jwt对应的playload数据存放在客户端
**Jwt优点**
1),减轻服务端压力。
2),查询效率比token高。
3),不容易被客户端篡改数据。
**缺点**
1)如果一旦生成好一个jwt之后,后期是否可以销毁
2)Jwt playload数据多,占据服务器端带宽资源
jwt不是很安全,playload中不能存放敏感的信息,必要须加密
**jwt注销**
无法做真正意义上的注销
1)用户注销时,直接将cookie缓存清除。
2)最好将jwt过期时间定义不要太长。
3)每个用户对应的盐值不一样,用户注销的时候直接将该盐值发生变化。