package com.netty.demo.filter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netty.demo.utls.JwtUtils;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
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.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
@Component
@RefreshScope
public class AuthorizeFilter implements GlobalFilter, Ordered {
@Value("${tokenUrl}")
private String tokenUrl;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1 获取请求对象
ServerHttpRequest request = exchange.getRequest();
//2 获取响应对象
ServerHttpResponse response = exchange.getResponse();
//3 判断当前请求是否是登录请求,如果是则放行
if(tokenUrl.contains(request.getURI().getPath())){
return chain.filter(exchange);
}
//4 获取当前所有请求头信息
HttpHeaders headers = request.getHeaders();
//5 获取JWT令牌信息
String Jwttoken = headers.getFirst("token");
//6 判断当前令牌是否存在
if(StringUtils.isEmpty(Jwttoken)){
//6.1 如果令牌存在,解析jwt令牌,判断令牌是否和法,如果不和法返回错误的提示信息
return out(response,"token异常");
}
//6.2令牌解析
boolean result = JwtUtils.checkToken(Jwttoken);
if (result){
String id = JwtUtils.getMemberIdByJwtToken(Jwttoken);
String user = stringRedisTemplate.opsForValue().get(id + "_tk");
if (ObjectUtils.isEmpty(user)){
return out(response,"登陆已过期");
}
JSONObject jsonObject = JSON.parseObject(user);
Object tk = jsonObject.get("tk");
if (!tk.equals(Jwttoken)){
return out(response,"登陆已过期");
}
stringRedisTemplate.expire(id+"_tk",30,TimeUnit.MINUTES);
//6.2令牌解析成功 ,则放行
ServerWebExchange ex = exchange.mutate().request(builder -> {
try {
builder.header("token2", URLEncoder.encode(user, "utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}).build();
return chain.filter(ex);
//return chain.filter(exchange);
}else {
return out(response,"token异常");
}
}
@Override
public int getOrder() {
return 0;
}
private Mono<Void> out(ServerHttpResponse response,String message) {
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type","application/json;charset=UTF-8");
DataBuffer buffer = response.bufferFactory().wrap(("{\n"
+ " \"code\": \"20001\","
+ " \"message\": \""+message+"\","
+ " \"data\": \"\","
+ " \"success\": false"
+ "}").getBytes(StandardCharsets.UTF_8));
return response.writeWith(Mono.just(buffer));
}
}