Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3599473
  • 博文数量: 365
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2522
  • 用 户 组: 普通用户
  • 注册时间: 2019-10-28 13:40
文章分类

全部博文(365)

文章存档

2023年(8)

2022年(130)

2021年(155)

2020年(50)

2019年(22)

我的朋友

分类: Java

2021-07-22 17:20:06

import cn.hutool.core.util.ObjectUtil;

import com.auth0.jwt.JWT;

import com.auth0.jwt.JWTVerifier;

import com.auth0.jwt.algorithms.Algorithm;

import com.auth0.jwt.interfaces.DecodedJWT;

import com.jwt.demo.config.UserLoginPermission;

import com.jwt.demo.db.bean.UserRole;

import com.jwt.demo.db.mapper.UserRoleMapper;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

import javax.servlet.http.HttpServletRequest;

import java.util.Date;

/**

 * token 工具类

 * @author chenlirun

 * @date 2021/7/8 17:27

 */

@Component

public class UserLoginTokenUtil {

    /**

     * 查询用户访问权限

     * @author chenlirun

     * @date 2021/7/18 17:36

     */

    @Autowired

    private UserRoleMapper userRoleMapper;

    // 静态实例化类对象

    private static UserLoginTokenUtil userLoginTokenUtil;

    /**

     * @PostConstruct

     * 1、首先这个注解是由Java提供的,它用来修饰一个非静态的void方法。它会在服务器加载Servlet的时候运行,并且只运行一次。

     * 2、用于处理普通工具类中方法无法被 static修饰,加入这个注解之后就可以在类初始化之前执行这个注解下的方法。

     * 3、我这个就是工具类中无法注入 mapper

     */

    @PostConstruct

    public void init(){

        userLoginTokenUtil=this;

    }

    //设置 token 过期时间为 30 分钟

    public static final long EXPIRE_TIME=30*60*1000;

    /**

     * 生成 token 签名,30分钟后过期

     *

     * @author chenlirun

     * @date 2021/7/8 17:52

     */

    public static String sign(Long id){

        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);

        // 设置jwt 令牌,Algorithm.HMAC256() 加密令牌

        Algorithm algorithm = Algorithm.HMAC256(TokenLoginInfo.secret);

        return JWT.create().withClaim("id",id) // 设置属性,可以是当前登录的用户信息,给 Payload

                .withExpiresAt(date) // 设置过期时间

                .withIssuedAt(new Date()) // 设置当前创建时间

                .sign(algorithm); // 签发一个新的jwt 令牌

    }

    /**

     * 校验 token

     * @author chenlirun

     * @date 2021/7/8 17:56

     */

    public static boolean verify(String token,Long id,String secret){

        try {

            Algorithm algorithm = Algorithm.HMAC256(secret);

            /**

             * JWT.require(): 验证签名的算法

             * .build(): 使用已经提供的配置创建一个新的可重用的JWTVerifier实例。

             *          返回:一个新的jwtverification实例。

              */

            JWTVerifier verifier = JWT.require(algorithm).withClaim("id", id).build();

            verifier.verify(token);

            return true;

        }catch (Exception e){

            return false;

        }

    }

    /**

     * 解析tokenid

     * @author chenlirun

     * @date 2021/7/9 11:20

     */

    public static Long getTokenById(HttpServletRequest request){

        String token = request.getHeader("token");

        /**

         * 解码给定的Json Web令牌。

         * 注意,这个方法并不验证令牌的签名!只有在您信任令牌或您已经验证了它时才使用它。

         * 返回:解码后的jwt。抛出:JWTDecodeException

         * -如果令牌的任何部分包含一个无效的jwt或每个jwt部分的JSON格式。

         */

        DecodedJWT decode = JWT.decode(token);

        return decode.getClaim("id").asLong();

    }

    /**

     * 认证token

     * @author chenlirun

     * @date 2021/7/16 14:56

     */

    public static boolean validToken(HttpServletRequest request, UserLoginPermission tag){

        String token = request.getHeader("token");

        if(token==null){

            throw new BaseException(BaseCodeResult.ERROR,"当前未登录");

        }

        Long userId = UserLoginTokenUtil.getTokenById(request);

        // 验证 token 签名

        System.out.println(TokenLoginInfo.secret);

        boolean verifySuccess = UserLoginTokenUtil.verify(token, userId, TokenLoginInfo.secret);

        if(!verifySuccess){

            throw new BaseException(BaseCodeResult.ERROR,"token 签名不正确");

        }

        // 验证访问权限

        UserRole userRole = userLoginTokenUtil.userRoleMapper.selectByUserId(userId);

        Byte roleId = userRole.getRoleId();

        if (ObjectUtil.isEmpty(userRole)){

            throw new BaseException(BaseCodeResult.ERROR,"该用户无可用权限");

        }

        /**

         * String.indexOf()

         * 返回此字符串中指定子字符串的第一个匹配项的索引。

         * 返回的索引是k中最小的值:.开始与(斯特,k)如果kexists没有这个值,则返回-1

         * str -要搜索的子字符串。

         * 返回:指定子字符串第一个匹配项的索引,如果没有匹配项则返回-1

         */

        int i = tag.role().indexOf(String.valueOf(roleId));

        if(i == -1){

            throw new BaseException(BaseCodeResult.ERROR,"无访问权限");

        }

        return true;

    }

}

阅读(1013) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~