JSON Web Token(JWT)是目前都在用的前后分离跨域验证规则。
JWT由3部分组成
1、引入依赖pom.xml
-
- <dependency>
- <groupId>com.auth0groupId>
- <artifactId>java-jwtartifactId>
- <version>3.8.2version>
- dependency>
2、编写jwt工具类JwtUtil.java
- package com.muchuantong.util;
-
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- import com.auth0.jwt.JWT;
- import com.auth0.jwt.JWTVerifier;
- import com.auth0.jwt.algorithms.Algorithm;
- import com.auth0.jwt.interfaces.Claim;
- import com.auth0.jwt.interfaces.DecodedJWT;
-
- /**
- * @Author: Zou Tiancong
- * @Date: 2021/12/1 0001 10:37
- * @Annotation:jwtToken
- */
- public class JwtUtil {
-
- // 设置过期时间
- private static final long EXPIRE_DATE = 60*1000;
- // token秘钥
- private static final String TOKEN_SECRET = "TEST-AUTH-TOKEN";
-
- // 实现签名方法
- public static String token(String id, String openId, String nickName) {
-
- String token = "";
- try {
- // 这里将用户存入了Token,在下面的解析中,也会有解析的方法可以获取到Token里面的数据
- // Token过期的时间
- Date expireDate = new Date(System.currentTimeMillis() + EXPIRE_DATE);
- // 秘钥及加密算法
- Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
- // 设置头部信息,类型以及签名所用的算法
- Map
header = new HashMap<>(); - header.put("typ", "JWT");
- header.put("alg", "HS256");
- // 携带用户信息,存入token,生成签名
- token = JWT.create()
- .withHeader(header) //设置头部信息Header
- .withIssuer("TEST") //设置签名是由谁生成
- .withSubject("AUTH-TOKEN") //设置签名的主题
- .withAudience(nickName) //设置签名的观众
- .withIssuedAt(new Date()) //设置生成签名的时间
- .withExpiresAt(expireDate) //设置签名过期的时间
- .withClaim("id", id) //自定义信息
- .withClaim("openId", openId)//自定义信息
- .withClaim("nickName", nickName)//自定义信息
- .withJWTId(id) //jwt的id,主要用来作为一次性token,从而回避重放攻击
- .sign(algorithm);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- return token;
- }
-
- // 验证token
- public static boolean verify(String token) {
- /**
- * @desc 验证token,通过返回true
- * @params [token]需要校验的串
- **/
- try {
- Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
- JWTVerifier verifier = JWT.require(algorithm).build();
- DecodedJWT jwt = verifier.verify(token);
- String subject = jwt.getSubject();
- List
audience = jwt.getAudience(); - Map
claims = jwt.getClaims(); - System.out.println(subject+"*******"+audience);
- for (Map.Entry
entry : claims.entrySet()){ - String key = entry.getKey();
- Claim claim = entry.getValue();
- String value = claim.asString();
- System.out.println("key:"+key+" value:"+value);
- }
- return true;
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println("Token已过期,需要重新登录");
- }
- return false;
- }
-
- // 生成token
- public static String setToken(String id, String openId, String nickName) {
- String token = token(id, openId, nickName);
- return token;
- }
-
- }
2、自定义注解接口Auth.java
- package com.muchuantong.util;
-
- import java.lang.annotation.*;
-
- /**
- * Created with IntelliJ IDEA.
- *
- * @Auther: ZouTiancong
- * @Date: 2022/05/23/22:37
- * @Description:
- */
- @Target({ ElementType.TYPE, ElementType.METHOD })
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface Auth {
- boolean token() default true;
- }
3、自定义注解APO实现类AuthAspect.java
- package com.muchuantong.util;
-
- import javax.servlet.http.HttpServletRequest;
-
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Pointcut;
- import org.aspectj.lang.reflect.MethodSignature;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
-
- /**
- * Created with IntelliJ IDEA.
- *
- * @Auther: ZouTiancong
- * @Date: 2022/05/23/22:39
- * @Description:
- */
- @Component
- @Aspect
- public class AuthAspect {
- @Autowired
- private HttpServletRequest request;
-
- @Pointcut("@annotation(com.muchuantong.util.Auth)")
- private void authPointcut() {
- }
-
- @Around("authPointcut()")
- public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
- // 获取方法签名信息从而获取方法名和参数类型
- MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
-
- // 获取目标方法对象上注解中的属性值
- Auth auth = methodSignature.getMethod().getAnnotation(Auth.class);
-
- // 校验签名
- if (auth.token()) {
- boolean token = JwtUtil.verify(request.getHeader("token"));
- // 如果token校验失败返回
- if (!token) {
- return new Result<>("401", "token已过期,请重新登录!");
- }
- }
- return joinPoint.proceed();
- }
- }
4、在需要token验证的地方加入注解@Auth

5、前端调用查看效果,token生成返回成功,后端也能成功读取数据

