token生成方法
//token生成方法
public class JwtUtil {
private static long time = 1000 * 60 * 60 * 24 * 1; //设置 JWT 的有效期为2天
public static String signature = "admin";
public static String createToken(String username) {
JwtBuilder jwtBuilder = Jwts.builder();
String jwtToken = jwtBuilder
.setHeaderParam("typ", "JWT") //header 类型 (typ)
.setHeaderParam("alg", "HS256") //算法 (alg)
.claim("username", username) //payload
.setExpiration(new Date(System.currentTimeMillis() + time)) //过期时间
.setId(UUID.randomUUID().toString()) //随机种子
.signWith(SignatureAlgorithm.HS256, signature) //signature
.compact();
System.out.println(jwtToken);
return jwtToken;
}
}
token验证方法
//token验证方法
import static com.example.mall.utils.JwtUtil.signature;
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (shouldIntercept(request)) {
// 拦截器逻辑
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer")) {
String token = authHeader.substring(7);
System.out.println("token:" + token);
try {
Claims claims = Jwts.parser()
.setSigningKey(signature)
.parseClaimsJws(token)
.getBody(); //获取claims内容,包含了用户名等信息
// 获取用户名
String username = (String) claims.get("username");
System.out.println("username1:" + username);
Date exp = claims.getExpiration();// 获取token过期时间
Date now = new Date();
// 判断是否过期
if (now.after(exp)) {
// token已过期,返回错误响应或者抛出异常
throw new ExpiredJwtException(null, null, "Token expired");
}
} catch (ExpiredJwtException e) {
// 处理过期的令牌
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.getWriter().write(JSON.toJSONString("Token is expired"));
return false;
} catch (Exception e) {
// 其他解析失败的情况
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.getWriter().write(JSON.toJSONString("Token is valid"));
return false;
}
}
}
return true;
}
private boolean shouldIntercept(HttpServletRequest request) {
// 在特定请求头存在时拦截
String authHeader = request.getHeader("Authorization");
return authHeader != null;
}
}
报错
原因
字母的确完全一致,但是还有不和谐的因素:前端返回的token包含引号!!!
就是因为这一小小引号,导致token被篡改,解析失败,让我找bug找了3天。。。
// 添加请求拦截器
service.interceptors.request.use(
config => {
// 设置 header
const token = localStorage.getItem('token')
if (token) {
// 这里导致了引号。。。
config.headers.Authorization = `Bearer ${token}`
}
config.headers.Aut = "header_test"
return config
},
error => {
return Promise.reject(error)
}
)
其他表头没有引号: