JWT【token】令牌
一、什么是JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。简单来说就是 JWT(Json Web Token)是实现token技术的一种解决方案;
二、基于token的鉴权机制
基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。除了用户id之外,还可以存储其他的和用户相关的信息,例如用户角色,用户性别等。
请求流程:
- 用户使用用户名密码来请求服务器
- 服务器进行验证用户的信息
- 服务器通过验证发送给用户一个token
- 客户端存储token,并在每次请求时附送上这个token值
- 服务端验证token值,并返回数据
这个token必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持 CORS(跨来源资源共享)
策略,一般我们在服务端这么做就可以了 Access-Control-Allow-Origin: *
。
三、JWT的结构
加密后jwt信息如下所示,是由"."分割的三部分组成,分别为Header、Payload、Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJjbGFpbXMiOnsibmFtZSI6IjE1MjkxMzk0Mzg1IiwiaWQiOjEwMjF9LCJleHAiOjE3MjU5Mzk2NTB9
.sAFhU06M550JDVgtOvR_ElauJwBU3jCFcKT8HOuJbFU
四、直上代码
首先咱们肯定是需要引入依赖包滴
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>4.4.0</version> <scope>compile</scope> </dependency>
其次就是正式的代码喽~【我这个是在测试里面写的哦~】
package com.example.tests; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; import org.junit.jupiter.api.Test; import java.io.UnsupportedEncodingException; import java.util.Calendar; import java.util.Date; public class Jwt_Token { //生成token @Test public void createToken() throws UnsupportedEncodingException { Calendar instance = Calendar.getInstance(); instance.add(Calendar.SECOND,100); String token = JWT.create() .withClaim("userid","123") .withClaim("username","Laugh") .withClaim("num",123) .withExpiresAt(new Date(System.currentTimeMillis()+1000*60))//当前设置有效时间为1分钟;new Date(System.currentTimeMillis()+1000*60*60*3) 这个为3小时 .sign(Algorithm.HMAC256("123")); System.out.println(token); } //解密token @Test public void verifyToken() throws UnsupportedEncodingException { JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("123")).build(); DecodedJWT verify = jwtVerifier.verify("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGFpbXMiOnsibmFtZSI6IjE1MjkxMzk0Mzg1IiwiaWQiOjEwMjF9LCJleHAiOjE3MjU5Mzk2NTB9.sAFhU06M550JDVgtOvR_ElauJwBU3jCFcKT8HOuJbFU"); System.out.println(verify.getClaim("userid").asString()); System.out.println(verify.getClaim("username").asString()); System.out.println(verify.getClaim("num").asInt()); } }
五、单元测试运行
5.1)生成token
5.2)解密token【解释:因为我这边测试设置的有效时长是1分钟 所以token发生了变化,可忽略~】
5.3)需注意哦~
注意:咱们需要注意 密钥(生成/解密) 必须保持一致哦~
我是生成【.sign(Algorithm.HMAC256("123"));】此刻生成密钥是123
我是解密【JWT.require(Algorithm.HMAC256("123")).build();】此刻解密密钥是123
六、JWT工具类(随便写了一个简单的工具类)
package com.example.tests.utils; import java.util.Date; import java.util.Map; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; public class JwtUtil { private static final String KEY = "Laugh"; //接收业务数据,生成token并返回 public static String genToken(Map<String, Object> claims) { return JWT.create() .withClaim("claims", claims) .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 1)) .sign(Algorithm.HMAC256(KEY)); } //接收token,验证token,并返回业务数据 public static Map<String, Object> parseToken(String token) { return JWT.require(Algorithm.HMAC256(KEY)) .build() .verify(token) .getClaim("claims") .asMap(); } }
争取摘到月亮,即使会坠落。