jjwt Token机制工具类封装

1 篇文章 0 订阅

一,使用场景
1.登录校验
2.信息加密

导入jar

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

二,代码实现(AOP+自定义注解+JWT)代码实现登录校验

自定义注解

package com.xy.login;

import java.lang.annotation.*;

/**
* @Target - 当前注解的作用范围
*  ElementType.CONSTRUCTOR - 能够标注在构造方法上
*  ElementType.FIELD - 能够标注在属性(全局变量)上
*  ElementType.LOCAL_VARIABLE - 能够标注在局部变量上
*  ElementType.METHOD - 方法上
*  ElementType.PARAMETER - 方法形参
*  ElementType.TYPE - 类、接口、内部类
*
* @Retention - 当前注解的有效范围
*  RetentionPolicy.SOURCE - 表示当前注解在源码中有效,一旦编译成class文件,注解会丢失
*  RetentionPolicy.CLASS - 表示当前注解在源码、class文件中有效,一旦运行时,就会丢失
*  RetentionPolicy.RUNTIME - 表示当前注解运行时有效,如果需要配合反射使用,必须是Runtime范围
*
* 方法语法: 返回值类型 方法名() [default 默认值];
*/
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IsLogin {

   boolean mustLogin() default false;
}

AOP

       package com.xy.login;

import com.xy.entity.ResultData;
import com.xy.entity.User;
import com.xy.tool.JwtUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 切面类
 *
 * 前置
 * 后置
 * 环绕
 * 异常
 * 后置完成
 *
 */
@Aspect
@Component
public class LoginAop {

    /**
     * 环绕增强
     * @param joinPoint
     * @return
     */
    @Around("@annotation(IsLogin)")
    public Object isLogin(ProceedingJoinPoint joinPoint){

        //前置增强
        
        //通过请求获得jwtToken和devId
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        //通过参数获取jwtToken和devId
        String jwtToken = request.getParameter("jwtToken");
        String devId = request.getParameter("devId");

        User user = null;

        //判断
        if(jwtToken != null && devId != null){
            //有可能登录
            user = JwtUtil.isToken(jwtToken, devId);
        }

        if(user == null){
            //说明未登录
            //获取方法上的IsLogin注解,判断mustLogin方法的返回值
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            IsLogin isLogin = method.getAnnotation(IsLogin.class);

            boolean flag = isLogin.mustLogin();
            if (flag){
                //强制登录
                //通知前端
                return new ResultData().setCode(ResultData.Code.TOLOGIN);
            }
        }

        //设置登录的用户信息 使用
        UserUtil.setUser(user);

        Object result = null;
        try {
            //目标方法的调用
            result = joinPoint.proceed();
            
            //后置增强
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            //异常增强
        } finally {
            //后置完成增强
        }

        return result;
    }
}

JwtUtil

package com.xy.tool;

import com.qf.entity.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtUtil {

    /**
     * 密钥
     */
    private static final String secrt = "21laksdfiua42131giuwgelkwqjrlkjhadklsf";
    /**
     * 密钥1天过期
     */
    private static final Integer timeout = 1000 * 60 * 60 * 24;

    /**
     * 生成JWT的令牌
     * @return
     */
    public static String createJwtToken(User user, String devId){
        JwtBuilder builder = Jwts.builder()
                .setId(user.getId() + "")
                .setSubject(user.getNickname())
                .setIssuedAt(new Date())
                //添加自定义属性
                .claim("uid", user.getId())
                .claim("username", user.getUsername())
                //设置jwt的过期时间
                .setExpiration(new Date(System.currentTimeMillis() + timeout))
                .signWith(SignatureAlgorithm.HS256,secrt + devId);

        String jwtToken = builder.compact();
        return jwtToken;
    }

    /**
     * 验签token的方法
     */
    public static User isToken(String jwtToken, String devId){
        try {
            Claims claim = Jwts.parser().setSigningKey(secrt + devId)
                    .parseClaimsJws(jwtToken).getBody();

            System.out.println("验签通过");
            //解析出用户的自定义信息
            Integer uid = (Integer) claim.get("uid");
            String username = (String) claim.get("username");
            User user = new User().setId(uid).setUsername(username);
            return user;
        } catch (Exception e) {
            System.out.println("验签未通过!");
        }

        return null;
    }
}

ThreadLocal 保存用户信息

public class UserUtil {

    private static ThreadLocal<User> user = new ThreadLocal<>();

    public static User getUser() {
        return UserUtil.user.get();
    }

    public static void setUser(User user) {
        UserUtil.user.set(user);
    }
    }

先登录获取Token

String jwtToken = JwtUtil.createJwtToken(user, devId);

通过注解的方式就可以实现环绕增强。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值