• 使用JWT登录生成token


    package com.example.demo.util;
    
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.JWTVerifier;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.exceptions.JWTVerificationException;
    import com.auth0.jwt.interfaces.Claim;
    import com.auth0.jwt.interfaces.DecodedJWT;
    import org.apache.commons.lang3.time.DateUtils;
    
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     *依赖:
            <dependency>
               <groupId>com.auth0</groupId>
               <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
            </dependency>
            <dependency>
            <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.7</version>
            </dependency>
     *
     *
     *
     *
     */
    
    public abstract  class JWTUtil {
        /**
         *  JWT 由3部分组成: header(Map集合),playload(负载,也可以把它看做请求体body,也是一个map集合),signature(签名,有header和playload加密后再跟secrect加密生成)
         *  header:有2个值,一个是类型,一个是算法,类型就是JWT,不会变,算法有2种选择,HMAC256和RS256,基本选择HMAC256
         *  playload:类似于post请求的请求体,是一个map集合,可以存很多很多值,如存用户的信息
         *  signature:由header(Base64加密后)和playload(Base64加密后)再加上secrect(秘钥生成)
         *  Base64加密是可逆的,所以存在header和playload的数据不能是敏感数据
         *
         *  playload有一些值定义:
         *
         *
    
         iss: jwt签发者
    
         sub: jwt所面向的用户
    
         aud: 接收jwt的一方
    
         exp: jwt的过期时间,这个过期时间必须要大于签发时间
    
         nbf: 定义在什么时间之前,该jwt都是不可用的.
    
         iat: jwt的签发时间
    
         jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
    
         *
         * @param userId 用户编号
         * @param secrect 秘钥(密码)
         * @param expireTime 过期时间单位s
         * @return
         */
        public static String getToken(String userId,String secrect,int expireTime){
            Date createDate = new Date();
            Date expireDate = DateUtils.addSeconds(createDate, expireTime);
            Map<String, Object> header = new HashMap<>();
            header.put("alg", "HS256");
            header.put("typ", "JWT");
            //token创建底层使用的是设计模式中的创建者模式,了解该模式对于下面的代码比较容易理解
            String token = JWT.create().withHeader(header)
                    .withClaim("userId", userId) //playload的一部分:withClaim底层是一个map,可以不断使用链式表达式存数据
                    .withIssuedAt(createDate)//创建时间 //playload的一部分
                    .withExpiresAt(expireDate) //过期时间 //playload的一部分
                    .sign(Algorithm.HMAC256(secrect));//生成 signature
            return token;
    
        }
        //如果token过期了,解析时就会报错,所以捕捉到异常时就知道是否过期了
        public static DecodedJWT decodeToken(String token, String secretKey) {
            DecodedJWT jwt = null;
    
            try {
                JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secretKey)).build();
                jwt = verifier.verify(token);
                return jwt;
            } catch (JWTVerificationException ex) {
                System.out.println("token 过期了");
                throw ex;
            }
        }
    
        //也可以通过token不需要密钥直接获取 DecodedJWT
        public static DecodedJWT decodedToken(String token){
            DecodedJWT decode = JWT.decode(token);
            return decode;
            //Map<String, Claim> claims = decode.getClaims();
        }
        //获取payLoad的值
        public static Object getUserId(String token,String userId,String secrect){
            DecodedJWT decodedJWT = decodeToken(token, secrect);
            Map<String, Claim> claims = decodedJWT.getClaims();
            Claim claim = claims.get(userId);//也可以通过claims获取其他值,具体根据存到playlaod里面的数据来取值
            return claim.asString();
        }
    
        public static String login(String userName,String password){
    
    
              User usr=userService.findUserByUserIdAndPassword(userName,password);
              if(null==usr){
                  System.out.println("账号或密码错误");
                  return null;
              }
    
             String token = getToken(usr.getUserId,password,86400);//1天过期
    
             token一旦生成,就没法修改,只有到过期时间后,才会失效,所以可以使用redis处理,用户每登录一次,就生成新的token
    
             redisUtil.set("login:user:"+usr.getUserId,token,86400);//用户每登录一次就会替换一次
             return token;
    
    
    
    
            return null;
        }
        public static boolean checkToken(String userId,String token){
            if(null==token){
                return false;
            }
    
            String token2=redisUtil.get("login.user:"+userId);
            if(!token.equal(token2)){
                return false;
            }
    
    
    
            return true;
        }
    
    }
  • 相关阅读:
    线性最大子数组的求法(二)
    高难度智力题
    职业规划
    良好的学习习惯
    毕业生面试绝招
    编写Java程序最容易犯的21种错误
    spring02
    spring_01
    用soapUI生成客户端代码
    idea创建git分支
  • 原文地址:https://www.cnblogs.com/yangxiaohui227/p/11190708.html
Copyright © 2020-2023  润新知