网关认证过滤器 - 校验JWT【黑马头条】
一、Filter
package com.heima.app.gateway.filter; import com.heima.app.gateway.util.JwtUtil; import io.jsonwebtoken.Claims; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component @Slf4j public class AuthorizeFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1.获取 request 和 response ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); // 2.判断是否是登录 if (request.getURI().getPath().contains("/login")) { //放行 return chain.filter(exchange); } // 3.获取 token String token = request.getHeaders().getFirst("token"); // 4.判断 token 是否存在 if (StringUtils.isBlank(token)) { response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } // 5.判断 token 是否有效 try { Claims claimsBody = JwtUtil.getClaimsBody(token); // 是否是过去 int result = JwtUtil.verifyToken(claimsBody); if (result == 1 || result == 2) { response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } } catch (Exception e) { e.printStackTrace(); response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } // 6.放行 return chain.filter(exchange); } /** * 优先级设置 值越小 优先级越高 * @return */ @Override public int getOrder() { return 0; } }
二、JwtUtil
package com.heima.app.gateway.util; import io.jsonwebtoken.*; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.util.*; public class JwtUtil { // TOKEN的有效期一天(S) private static final int TOKEN_TIME_OUT = 3_600; // 加密KEY private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY"; // 最小刷新间隔(S) private static final int REFRESH_TIME = 300; // 生产ID public static String getToken(Long id){ Map<String, Object> claimMaps = new HashMap<>(); claimMaps.put("id",id); long currentTime = System.currentTimeMillis(); return Jwts.builder() .setId(UUID.randomUUID().toString()) .setIssuedAt(new Date(currentTime)) //签发时间 .setSubject("system") //说明 .setIssuer("heima") //签发者信息 .setAudience("app") //接收用户 .compressWith(CompressionCodecs.GZIP) //数据压缩方式 .signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式 .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳 .addClaims(claimMaps) //cla信息 .compact(); } /** * 获取token中的claims信息 * * @param token * @return */ private static Jws<Claims> getJws(String token) { return Jwts.parser() .setSigningKey(generalKey()) .parseClaimsJws(token); } /** * 获取payload body信息 * * @param token * @return */ public static Claims getClaimsBody(String token) { try { return getJws(token).getBody(); }catch (ExpiredJwtException e){ return null; } } /** * 获取hearder body信息 * * @param token * @return */ public static JwsHeader getHeaderBody(String token) { return getJws(token).getHeader(); } /** * 是否过期 * * @param claims * @return -1:有效,0:有效,1:过期,2:过期 */ public static int verifyToken(Claims claims) { if(claims==null){ return 1; } try { claims.getExpiration() .before(new Date()); // 需要自动刷新TOKEN if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){ return -1; }else { return 0; } } catch (ExpiredJwtException ex) { return 1; }catch (Exception e){ return 2; } } /** * 由字符串生成加密key * * @return */ public static SecretKey generalKey() { byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes()); SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES"); return key; } public static void main(String[] args) { /* Map map = new HashMap(); map.put("id","11");*/ System.out.println(JwtUtil.getToken(1102L)); Jws<Claims> jws = JwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA"); Claims claims = jws.getBody(); System.out.println(claims.get("id")); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」