1、jwt令牌
1、是一种开放标准,定义了一种紧凑的、自包含的方式,用于作为不同域之间的两方之间安全地表示声明
2、导包
<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>
3、导入工具类,jwt生成与检验参考工具类中main中的用法
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JWTUtil {
private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);
public static String generateToken(Map<String, Object> claims, int expirationSeconds) {
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + expirationSeconds * 1000L))
.signWith(SECRET_KEY, SignatureAlgorithm.HS256)
.compact();
}
public static Claims validateToken(String token) {
try {
return Jwts.parserBuilder()
.setSigningKey(SECRET_KEY)
.build()
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
throw new RuntimeException("Token校验失败: " + e.getMessage());
}
}
public static void main(String[] args) {
Map<String, Object> claims = new HashMap<>();
claims.put("user_id", 123);
claims.put("username", "example_user");
String token = generateToken(claims, 3600);
System.out.println("生成的JWT令牌: " + token);
try {
Claims validatedClaims = validateToken(token);
System.out.println("校验成功,解码后的数据: " + validatedClaims);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
2、过滤器(Filter)
1、会拦截所有的资源
2、springboot启动类上添加@ServletComponentScan注解
3、自定义类TokenFilter实现Filter接口
package com.example.config;
import com.example.tool.JWTUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@WebFilter(urlPatterns = "/*")
public class TokenFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String url = request.getRequestURL().toString();
String token = request.getHeader("token");
if (url.contains("login")) {
filterChain.doFilter(request, response);
return;
}
if (token == null || token == "") {
response.setStatus(401);
log.error("token is Empty");
return;
} else {
try {
Claims validatedClaims = JWTUtil.validateToken(token);
System.out.println("校验成功,解码后的数据: " + validatedClaims);
filterChain.doFilter(request, response);
} catch (Exception e) {
e.printStackTrace();
log.error("token is Error");
response.setStatus(401);
}
}
}
}
3、拦截器(Interceptor)
1、只会拦截Spring环境中的资源
2、自定义类MyInterceptor 实现HandlerInterceptor 接口
package com.example.config;
import com.example.tool.JWTUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String url = request.getRequestURL().toString();
String token = request.getHeader("token");
if(token==null || token==""){
response.setStatus(401);
log.error("Myhandler:token is Empty");
return false;
}
else {
try {
Claims validatedClaims = JWTUtil.validateToken(token);
System.out.println("校验成功,解码后的数据: " + validatedClaims);
return true;
} catch (Exception e) {
response.setStatus(401);
log.error("Myhandler:token is Error");
e.printStackTrace();
return false;
}
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
3、在一个配置类中注册它,并指定要拦截的路径模式
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 WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/public/**");
}
}