@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) {
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{
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);
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
.setId("restkeeper")
.setIssuedAt(Date.from(zdt.toInstant()))
.setHeaderParam("alg", "HS256")
.addClaims(tokenMap)
.setExpiration(Date.from(zdt.toInstant()))
.signWith(signatureAlgorithm, secretKey);
return builder.compact();
}
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);
}
}
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);
}
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;
private int code;
private Map<String,Object> tokenMap;
public VerifyResult(boolean isValidate, int code) {
this.isValidate = isValidate;
this.code = code;
System.out.println("1111");
}
}
}
转载请注明原文地址:https://blackberry.8miu.com/read-39646.html