参考链接
基于Token的登录流程 - 腾讯云开发者社区-腾讯云 (tencent.com)
Java实现token的生成与验证-登录功能 - 穆晟铭 - 博客园 (cnblogs.com)
java SpringBoot登录验证token拦截器_springboot拦截器验证token_我要用代码向我喜欢的女孩表白的博客-CSDN博客
第一步:导入依赖
pom.xml文件
<!--jwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
第二步:书写工具类
package com.example.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 通过JWT制造token,设置token
*/
public class JwtUtil {
// 这是你的 JWT 密钥,请将其设置为更安全的值
private static final String SECRET_KEY = "dsfdfsdfdsfefrgssthJBIONPILOVEYOUyueyue";
/**
* 创建 JWT
*
* @param id JWT ID
* @param issuer 签发者
* @param subject 主题
* @param ttlHOURS JWT 有效期(小时)
* @param claims JWT 声明
* @return JWT 字符串
*/
public static String createJwt(String id, String issuer, String subject, long ttlHOURS, Map<String, Object> claims) {
// 设置 JWT 的签发时间和过期时间
Instant now = Instant.now();
Instant exp = now.plus(ttlHOURS, ChronoUnit.HOURS);
// 创建 JWT Builder
SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());
JwtBuilder builder = Jwts.builder()
.setId(id)
.setIssuer(issuer)
.setSubject(subject)
.setIssuedAt(Date.from(now))
.setExpiration(Date.from(exp))
.signWith(key);
// 添加声明
if (claims != null) {
builder.addClaims(claims);
}
// 构建 JWT 并返回
return builder.compact();
}
/**
* 解析 JWT
*
* @param jwt JWT 字符串
* @return JWT 声明
* @throws JwtException 如果 JWT 无效或已过期
*/
public static Map<String, Object> parseJwt(String jwt) throws JwtException {
// 解析 JWT
SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());
Claims claims = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(jwt)
.getBody();
// 将声明转换为 Map
// 返回声明
return new HashMap<>(claims);
}
}
第三步:创造拦截器
Interceptor.class
package com.example.interceptor;
import com.example.mapper.UserDao;
import com.example.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Interceptor implements HandlerInterceptor {
@Autowired
UserDao userDao;
/**
* 在请求拦截处理前进行token校验
*
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
//1.token不存在
if (token == null){
throw new RuntimeException("token不存在,请重新登录!");
}
//2.token是否正确
try{
JwtUtil.parseJwt(token).get("phone");
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("token验证失败或过期,请重新获取!");
}
return true;
}
}
1.此处验证token是否存在 2.验证解析的jwt中是否含有自己所带的参数
第四步:关联拦截器
InterceptorConfig.class
package com.example.config;
import com.example.interceptor.Interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
public Interceptor init(){
return new Interceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(init())
//拦截的URL
.addPathPatterns("/**")
//放行的URL
.excludePathPatterns("/user/**");
}
}
此处添加拦截配置
第五步:统一异常处理
package com.example.controller.utils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//作为springMVC的异常处理
//@ControllerAdvice
@RestControllerAdvice
public class ProjectExceptionAdvice {
//拦截所有的异常处理
@ExceptionHandler
public R doException(Exception e) {
String msg ="服务器异常,请稍后再试";
String data = e.getMessage();
if (data.contains("token")){
msg = data;
}
//记录日志
//通知运维
//通知开发
e.printStackTrace();//注意,打印日志,此处实际开发时容易忽略
return new R(R.UNDEFINED_CODE, null,msg);
}
}
此处验证token是使用 字符串中包含“token”字符串,而进行验证。自我感觉这样异常处理不合适请各位大佬指教。