jwt快速入门

1.介绍

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

实现是 一个 加密的字符串 ,这个字符串存储了用户的身份凭证 等信息

JWT一般不要携带太大的数据,不然每次请求都要处理太费时,所以一般是用JWT做认证,然后去redis里面取相应的角色权限信息。

2.快速开始

2.1添加依赖

 
        
            com.auth0
            java-jwt
            3.2.0
        
        
            io.jsonwebtoken
            jjwt
            0.7.0
        

2.2创建工具类

package com.zhp.sbdemo1.utils;
​
import com.zhp.sbdemo1.common.CheckResult;
import com.zhp.sbdemo1.common.SystemConstant;
import io.jsonwebtoken.*;
import org.bouncycastle.util.encoders.Base64;
​
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
​
/**
 * 前端发送认证请求   比如用户名密码   认证通过后  后台生成一个 token
 * 发送给前端  前端存储到 localstorage    以后每次请求 都带这个token  发送到后台 去验证
 *
 *
 *
 * @date 2021/5/9 20:44
 */
public class JwtUtils {
​
    /**
     * 签发JWT
     * @param id
     * @param subject 可以是JSON数据 尽可能少
     * @param ttlMillis
     * @return
     */
    public static String createJWT(String id, String subject, long ttlMillis) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey secretKey = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setSubject(subject)   // 主体  一般是用户名
                .setIssuer("axbhealj")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;  // 当前时间  + 有效时间
            Date expDate = new Date(expMillis);   // 过期时间
            builder.setExpiration(expDate); // 设置过期时间
        }
        return builder.compact();
    }
​
    /**
     * 验证JWT
     * @param jwtStr
     * @return
     */
    public static CheckResult validateJWT(String jwtStr) {
        CheckResult checkResult = new CheckResult();
        Claims claims = null;
        try {
            claims = parseJWT(jwtStr);
            checkResult.setSuccess(true);
            checkResult.setClaims(claims);
        } catch (ExpiredJwtException e) {
            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_EXPIRE);
            checkResult.setSuccess(false);
        } catch (SignatureException e) {
            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        } catch (Exception e) {
            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        }
        return checkResult;
    }
​
    /**
     * 生成加密Key
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.decode(SystemConstant.JWT_SECERT);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }
​
​
    /**
     * 解析JWT字符串
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }
​
    public static void main(String[] args) throws InterruptedException {
         // 后端生成token
        String sc=createJWT("1","jack",SystemConstant.JWT_TTL);
        System.out.println(sc);
​
        // 后端验证token
        CheckResult checkResult = validateJWT(sc);
        System.out.println(checkResult.isSuccess());
        System.out.println(checkResult.getErrCode());
        Claims claims=checkResult.getClaims();
        System.out.println(claims);
        System.out.println(claims.getId());
        System.out.println(claims.getSubject());
​
        // 刷新token 重新生成token
        Claims claims2=validateJWT(sc).getClaims();
        String sc2=createJWT(claims2.getId(),claims2.getSubject(),SystemConstant.JWT_TTL);
        System.out.println(sc2);
    }
​
}

配套 常量类 和 结果类

package com.zhp.sbdemo1.common;
​
/**
 * @date 2023/5/24
 * @desc
 */
public class SystemConstant {
    /**
     * token
     */
    public static final int JWT_ERRCODE_NULL = 4000;            //Token不存在
    public static final int JWT_ERRCODE_EXPIRE = 4001;          //Token过期
    public static final int JWT_ERRCODE_FAIL = 4002;            //验证不通过
​
    /**
     * JWT
     */
    public static final String JWT_SECERT = "8677df7fc3a34e26a61c034d5ec8245d";         //密匙
    public static final long JWT_TTL = 30 * 60 * 1000;                                  //token有效时间
}
​
package com.zhp.sbdemo1.common;
​
import io.jsonwebtoken.Claims;
​
/**
 * @date 2023/5/24
 * @desc
 */
public class CheckResult {
​
    private int errCode;
​
    private boolean success;
​
    private Claims claims;
​
    public int getErrCode() {
        return errCode;
    }
​
    public void setErrCode(int errCode) {
        this.errCode = errCode;
    }
​
    public boolean isSuccess() {
        return success;
    }
​
    public void setSuccess(boolean success) {
        this.success = success;
    }
​
    public Claims getClaims() {
        return claims;
    }
​
    public void setClaims(Claims claims) {
        this.claims = claims;
    }
}

3.认证成功 发送token

 @PostMapping("/login")
    public JsonResult login(@RequestBody User user){
        User currentUser = userService.login(user);
        if(currentUser==null){
            //认证失败
            return JsonResult.ok(currentUser);
        }else {
            //认证成功  向前端 发送token
            String token =   JwtUtils.createJWT(String.valueOf(currentUser.getUserId()),currentUser.getRealname(), SystemConstant.JWT_TTL);
            return JsonResult.ok(token);
        }
    }

4.前端接受token 并存起来 以后每次请求在请求头上携带token

   //整合  jwt  返回的是  token     后面的请求  就需要携带token
               var token  = resp.data.data;
                //把响应结果的token 存到 localStorage
               window.localStorage.setItem("token",token);

后续请求携带token

 let token = window.localStorage.getItem("token");
        
        this.axios.defaults.headers.common["token"] = token;  // 请求头上带token

你可能感兴趣的:(各种经验分享,java,前端,数据库)