cloud微服务-网关鉴权-安全登录-全局过滤器

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;
}

希望能够帮助到你们。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值