前后端分离的情况下,采用 jwt 下发 token 做鉴权。
至于为什么要用 jwt,这里不在赘述.
基于 springboot 的 jwt 实现
依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
JwtUtil.java
package com.jeffcail.javamall.util;
import com.jeffcail.javamall.constant.WxUserConstant;
import com.jeffcail.javamall.result.CheckResult;
import io.jsonwebtoken.*;
import org.bouncycastle.util.encoders.Base64;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
/**
* @ClassName JwtUtil
* @Description TODO
* @Author cc
* @Date 2023/6/8 10:46 下午
* @Version 1.0
*/
public class JwtUtil {
/**
* 签发 token
* @param id
* @param subject
* @param ttlMills
* @return
*/
public static String generateToken(String id, String subject, long ttlMills) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
SecretKey secretKey = generateKey();
JwtBuilder builder = Jwts.builder()
.setId(id)
.setSubject(subject) // 主体
.setIssuer("jeffcail") // 签发人
.setIssuedAt(now) // 签发时间
.signWith(signatureAlgorithm, secretKey); // 签名算法及密钥
if (ttlMills >= 0) {
long expireMills = nowMillis + ttlMills;
Date expireDate = new Date(expireMills);
builder.setExpiration(expireDate); // 过期时间
}
return builder.compact();}
/**
* token 验证
* @param token
* @return
*/
public static CheckResult validateToken(String token) {CheckResult checkResult = new CheckResult();
Claims claims = null;
try {claims = parseToken(token);
checkResult.setSuccess(true);
checkResult.setClaims(claims);
} catch (ExpiredJwtException e) {checkResult.setErrCode(WxUserConstant.TOKEN_IS_EXPIRE);
checkResult.setSuccess(false);
} catch (SignatureException e) {checkResult.setErrCode(WxUserConstant.TOKEN_IS_FAIL);
checkResult.setSuccess(false);
} catch (Exception e) {checkResult.setErrCode(WxUserConstant.TOKEN_IS_FAIL);
checkResult.setSuccess(false);
}
return checkResult;
}
private static SecretKey generateKey() {byte[] decode = Base64.decode(WxUserConstant.Jwt_Secret);
return new SecretKeySpec(decode, 0, decode.length, "AES");
}
/**
* 解析 token
* @param token
* @return
* @throws Exception
*/
public static Claims parseToken(String token) throws Exception {SecretKey secretKey = generateKey();
return Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token)
.getBody();}
}
WxUserContant.java
package com.jeffcail.javamall.constant;
/**
* @ClassName WxUserConstant
* @Description TODO
* @Author cc
* @Date 2023/6/8 10:51 下午
* @Version 1.0
*/
public class WxUserConstant {
public static final int TOKEN_IS_NOT = 4000; // token 不存在
public static final int TOKEN_IS_EXPIRE = 4001; // token 已过期
public static final int TOKEN_IS_FAIL = 4002; // token 无效 token
public static final String Jwt_Secret = "9677af3hc3a35e46a61n094d5jl9448f";
public static final long Jwt_Ttl = 1000 * 60 * 60 * 24 * 7;
}
CheckResult.java
package com.jeffcail.javamall.result;
import io.jsonwebtoken.Claims;
/**
* @ClassName CheckResult
* @Description TODO
* @Author cc
* @Date 2023/6/8 11:02 下午
* @Version 1.0
*/
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;}
}
控制器调用
// 利用 jwt 生成 token 返回到前端
String token = JwtUtil.generateToken(openid, wxUserInfo.getNickName(), WxUserConstant.Jwt_Ttl);
正文完