springcloud gateway过滤器模板代码检验token有没有

    科技2025-07-11  16

    @Component @RefreshScope public class AuthFilter implements GlobalFilter, Ordered { @Value("#{'${gateway.excludedUrls}'.split(',')}") private List<String> excludedUrls; @Value("${gateway.secret}") private String secret; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //获取响应对象 ServerHttpResponse response = exchange.getResponse(); //获取当前请求路径 String path = exchange.getRequest().getURI().getPath(); //排除特殊不需要令牌的路径 if (excludedUrls.contains(path)){ return chain.filter(exchange); } //获取令牌信息 String token = exchange.getRequest().getHeaders().getFirst("Authorization"); if (StringUtils.isNotEmpty(token)){ //合法性进行判断 JWTUtil.VerifyResult verifyResult = JWTUtil.verifyJwt(token, secret); if (verifyResult.isValidate()){ //令牌校验通过 return chain.filter(exchange); }else{ //令牌校验不通过 Map<String,Object> responseData = Maps.newHashMap(); responseData.put("code",verifyResult.getCode()); responseData.put("message","验证失败"); return responseError(response,responseData); } }else{ //令牌不存在 //返回错误信息 Map<String,Object> responseData = Maps.newHashMap(); responseData.put("code",401); responseData.put("message","非法请求"); responseData.put("cause","token is empty"); return responseError(response,responseData); } } //返回响应数据 private Mono<Void> responseError(ServerHttpResponse response, Map<String, Object> responseData) { //将信息转换为json ObjectMapper objectMapper = new ObjectMapper(); byte[] data = new byte[0]; try{ data = objectMapper.writeValueAsBytes(responseData); }catch (Exception e){ e.printStackTrace(); } //输出结果数据 DataBuffer buffer = response.bufferFactory().wrap(data); response.setStatusCode(HttpStatus.UNAUTHORIZED); response.getHeaders().add("Content-Type","application/json;charset=utf-8"); return response.writeWith(Mono.just(buffer)); } @Override public int getOrder() { return 0; } } 不需要检验的Url都放在nacos中的配置文件中了 用 @Value("#{’${gateway.excludedUrls}’.split(’,’)}") 进行获取从exchang中取出request请求对象和response对象,然后从request中取出token,判断有没有,有的话调用工具类中的JWTUtil是否合法,有效,有效的话就直接通过,无效的话就返回错误信息。返回的信息,在后端肯定刚开始都用map封装,然后传到前端肯定是以json传递,所以要将map转化为json数据,然后封装到response对象中,返回到前端

    下面是jwt加密解密、验证是否正确的代码,也是模板代码,作为工具代码

    public class JWTUtil{ /** * 签发JWT * @param tokenMap * @param secret * @return * @throws IOException */ public static String createJWTByObj(Map<String, Object> tokenMap, String secret) throws IOException { SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; SecretKey secretKey = generalKey(secret); ZoneId zoneId = ZoneId.systemDefault(); ZonedDateTime zdt = LocalDateTime.now().plusDays(3).atZone(zoneId); //添加构成JWT的参数 JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT") .setId("restkeeper") //签发应用Id .setIssuedAt(Date.from(zdt.toInstant())) //签发时间 .setHeaderParam("alg", "HS256") //加密算法 .addClaims(tokenMap) .setExpiration(Date.from(zdt.toInstant())) //设置过期时间 .signWith(signatureAlgorithm, secretKey); //用密钥签名 //生成JWT return builder.compact(); } /** * 验证jwt */ public static VerifyResult verifyJwt(String token, String secret) { //签名秘钥,和生成的签名的秘钥一模一样 SecretKey key = generalKey(secret); try { ZoneId zoneId = ZoneId.systemDefault(); ZonedDateTime zdt = LocalDateTime.now().atZone(zoneId); Jwt jwt = Jwts.parser() .setSigningKey(key) .parse(token); Date date = ((Claims) jwt.getBody()).getExpiration(); if (date == null) { return new VerifyResult(false, 5002); } LocalDateTime expires = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); if (expires.isBefore(LocalDateTime.now())) { return new VerifyResult(false, 5001); } return new VerifyResult(true, 200); } catch (Exception e) { e.printStackTrace(); return new VerifyResult(false, 5002); }//设置需要解析的jwt } public static Map<String,Object> decode(String token) throws IOException { String bodyData = token.split("\\.")[1]; String bodyStr = new String(Base64.decodeBase64(bodyData),"UTF-8"); return JSON.parseObject(bodyStr,Map.class); } /** * 生成key * * @param jwtSecret * @return */ private static SecretKey generalKey(String jwtSecret) { String stringKey = jwtSecret; byte[] encodedKey = Base64.decodeBase64(stringKey); SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES"); return key; } @Data public static class VerifyResult{ private boolean isValidate; /** * 5001:token过期;5002:无效token;5003:token校验异常 */ private int code; private Map<String,Object> tokenMap; public VerifyResult(boolean isValidate, int code) { this.isValidate = isValidate; this.code = code; System.out.println("1111"); } } }
    Processed: 0.012, SQL: 8