# JWT **Repository Path**: beimu_yc/jwt ## Basic Information - **Project Name**: JWT - **Description**: JWT - **Primary Language**: Java - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-05-12 - **Last Updated**: 2023-05-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # JWT #### 介绍 JWT ### 数据库 ```mysql CREATE TABLE `user` ( `id` int NOT NULL AUTO_INCREMENT COMMENT 'id', `name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户名', `password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户密码', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` # 认证流程 ![输入图片说明](image.png) ⾸先,前端通过Web表单将⾃⼰的⽤⼾名和密码发送到后端的接⼝。这⼀过程⼀般是⼀个HTTP POST请求。建议的⽅式是通过SSL加密的传输(https协议),从⽽避免敏感信息被嗅探。 1. 后端核对⽤⼾名和密码成功后,将⽤⼾的id等其他信息作JWT Payload (负载),将其与头部分别进⾏Base64编码拼接后签名,形成⼀JWT(Token)形成的JWT就是⼀个形同11.zzz.xxx的字符。tokenhead.payload(负载).signature(签名) 2. 后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT即可。 3. 前端在每次请求时将JWT放⼊HTTP Header中的Authorization位。(解决XSS和XSRF问题) 4. 后端检查是否存在,如存在验证JWT的有效性。 ◦ 检查签名是否正确; ◦ 检查Token是否过期; ◦ 检查Token的接收⽅是否是⾃⼰(可选) 5.验证通过后后端使⽤JWT中包含的⽤⼾信息进⾏其他逻辑操作,返回相应结果。 ### JWT优势在哪? 1. 简洁(Compact):可以通过URL, POST参数或者在HTTPheader发送,数据量⼩,传输速度快 2. ⾃包含(Self-contained):负载中包含了所有⽤⼾所需要的信息,避免了多次查询数据库 因为Token是以JSON加密的形式保存在客⼾端的,所以JWT是跨语⾔的,原则上任何web形式都 ⽀持。 3. 不需要在服务端保存会话信息,特别适⽤于分布式微服务。 ## JWT的结构 **令牌组成** - 1.标头(Header) - 2.有效载荷(Palyload) - 3.签名(Signature) - 因此,JWT通常如下所示:xxxxx.yyyyy.zzzzz Header.Playload.Signature **Header** - 标头通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法,例如HMAC SHA256或RSA。会使用Base64编码组成JWT的结构的一部分 - 注意:Base64是一种编码,也就是说,他是可以被翻译回原来的样子的。它并不是一种加密过程。 ```java { "alg":"HS256", "typ":"JWT" } ``` **Payload** - 令牌的第二部分是有效负载,其中包含声明。声明是有关于实体(通常是用户)和其他数据的声明。同样的,它会使用Base64编码组成JWT结构的第二部分 ```java { "sub":"1234567890", "name":"John Doe", "admin":true } ``` **Signature** - 前面两部分是使用Base64进行编码的,即前端可以解开知道里面的信息。Signature需要使用编码后的header和payload以及我们提供的一个密钥,然后使用header中指定的签名算法(HS256)进行签名的作用是保证JWT没有被篡改过 - 如: HMACSHA256(base64UrlEncode(header)+ "." + base64UrlEncode(payload),secret); **签名目的** - 最后一步签名的过程,实际上是对头部以及负载内容进行签名,防止内容被篡改。如果有人对头部以及负载的内容解码之后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。