cloud 微服务,我们使用的结构如下:(没使用配置中心,配置文件单独手动更新的)
springcloud-gateway:网关,给前台的统一的访问项目,在此处我做了一个网关鉴权,安全登录;
springcloud-hystrix-feign:路由,网关调到路由,在此处进行分发路径到各处业务项目,处理之外,熔断、超时也进行设置;
springcloud-turbin:项目监控,一般都是固定配置,在配置文件中,写入各项目的访问名
timerbatch-manage:定时项目,定时发送邮件短信
common-manage:数据字典项目、以及发送邮件短信
load-manage文件服务器项目
等系列业务项目
今天记录一下,网关鉴权,安全登录:会用到过滤器,我采用的是:GlobalFilter工具类
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Autowired
private StringRedisTemplate redisTemplate;//获取redis
private Logger logger = LoggerFactory.getLogger(AuthGlobalFilter.class);//打印控制台日志
private static final String AUTHORIZE_TOKEN = "token";//全局变量,获取token
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Map<String, Object> resultInfos = new HashMap<String, Object>();
System.out.println("Welcome to AuthGlobalFilter.");
logger.info("Welcome to AuthGlobalFilter.");
System.out.println("exchange信息:"+exchange);
logger.info("exchange信息:" + exchange);
ServerHttpRequest request = exchange.getRequest();
System.out.println("request信息:"+request.getQueryParams());
//get方式获取token,post我没获取成功。
String token1 = exchange.getRequest().getQueryParams().getFirst("token");
System.out.println("token1="+token1);
if (token1 == null) {
token1 = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
System.out.println("token为空"+token1);
//参数:
/* 此处可不看,post获取数据失败
//从请求里获取Post请求体
String bodyStr = resolveBodyFromRequest(request);
//下面的将请求体再次封装写回到request里,传到下一级,否则,由于请求体已被消费,后续的服务将取不到值
URI uri = request.getURI();
ServerHttpRequest request1 = request.mutate().uri(uri).build();
DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
request1 = new ServerHttpRequestDecorator(request1) {
@Override
public Flux<DataBuffer> getBody() {
return bodyFlux;
}
};
//封装request,传给下一级
Map<String,String> map = JSON.parseObject(toJSONString(request1),Map.class);
map.put("TOKEN",token1);
return chain.filter(exchange.mutate().request((ServerHttpRequest) map).build());*/
//没传token,为登录-要放过
return chain.filter(exchange);
}else{
//有效的token时-非 登录,要判断redis是否有值
boolean tokenExect = redisTemplate.hasKey(token1);
if(tokenExect){
logger.info("Redis有信息:"+redisTemplate.opsForValue().get(token1));
Map<String,Object> map1 = JSON.parseObject(redisTemplate.opsForValue().get(token1),Map.class);
//redisTemplate.delete(token1);//根据TOKEN删除缓存,别删除,重新定义token生效时间,否则,并发性高的时候,会登录报错
redisTemplate.opsForValue().set(token1,JSON.toJSONString(map1),60*30,TimeUnit.SECONDS);
/*
post获取参数失败,不用看此处
String metnod = request.getMethodValue();
logger.info("请求request信息:" + request);
if ("POST".equals(metnod)){
String bodyStr = getReqBody(request);
logger.info("body信息:" + bodyStr);
Map<String, Object> reqMap = JSON.parseObject(bodyStr);
reqMap.put("TOKEN", token1);
//重新封装请求
URI uri = request.getURI();
ServerHttpRequest requestAgen = request.mutate().uri(uri).build();
DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
requestAgen = new ServerHttpRequestDecorator(requestAgen) {
@Override
public Flux<DataBuffer> getBody() {
return bodyFlux;
}
};
//封装request,传给下一级
return chain.filter(exchange.mutate().request(requestAgen).build());
}*/
return chain.filter(exchange);
}else{
//token已过期
logger.info("Redis无信息:");
resultInfos.put("errCode","9999");
resultInfos.put("errMsg","密码错误");
//return JSON.toJSONString(resultInfos);
// return chain.filter(exchange);
if (true) {
ServerHttpResponse response = exchange.getResponse();
JSONObject message = new JSONObject();
message.put("errCode", "0002");
message.put("data", "登录信息已过期,请重新登录!!!");
byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bits);
//返回前台状态码
response.setStatusCode(HttpStatus.OK);
//指定编码,否则在浏览器中会中文乱码
response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
}
return chain.filter(exchange);
}
}
}
/**
* 获取请求体
* @param request
* @return
*/
private String getReqBody(ServerHttpRequest request) {
Flux<DataBuffer> body = request.getBody();
logger.info("获取body信息:" + JSON.toJSONString(body));
AtomicReference<String> bodyRef = new AtomicReference<>();
body.subscribe(buffer -> {
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
DataBufferUtils.release(buffer);
bodyRef.set(charBuffer.toString());
});
//获取request body
return bodyRef.get();
}
/**
* 从Flux<DataBuffer>中获取字符串的方法
* @return 请求体
*/
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
//获取请求体
Flux<DataBuffer> body = serverHttpRequest.getBody();
AtomicReference<String> bodyRef = new AtomicReference<>();
body.subscribe(buffer -> {
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
DataBufferUtils.release(buffer);
bodyRef.set(charBuffer.toString());
});
//获取request body
return bodyRef.get();
}
private DataBuffer stringBuffer(String value) {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
}
@Override
public int getOrder() {
return 0;
}
希望能够帮助到你们。