使用gateway网关实现分布式系统的token校验

最近在写自己的毕业设计,我本着能与众不同点就不同一点的想法,脑子一热决定,“要不用分布式来写个毕业设计吧”然后悲惨的生活开始了

问题出处

大家都知道http连接是无状态的,所以服务器压根不会知道你到底是谁,你来过吗?
所以咋办?用session咯!但是呢由于现在都流行前后端分离,这两玩意都不在同一个服务器上呀,那session就不能共享了呀。
所以就出现了一个好东西——token,它就像你每天上班都要带的工牌,你不带门口保安叔叔可不让你进去呀。
但是呢还有个问题,我这分布式好多个功能模块噢,那我不得每个模块都来个token检验,那多麻烦呀。好了废话那么多,本次主角该登场了。

什么是网关

网关是微服务最边缘的服务,直接暴露给用户,用来做用户和微服务的桥梁

网关能做啥呢

网关可以实现负载均衡,可 以实现 token 拦截,权限验证,限流等操作。
等等token拦截,权限验证,那不就可以对所有的请求进行token校验然后再路由转发给其他的功能模块了吗?所以请添加图片描述
那必须动手做呀

Gateway

在这里插入图片描述

从这张图我们可以看出来gateway的核心就是一个一个的过滤器,所以token拦截自然也是在过滤器中完成的啦。这里再上一个图请添加图片描述

token校验的实现


/**
 * 使用网关进行token校验拦截
 * 注意这里需要创建这个对象所以需要依赖注入创建
 * */
@Component
public class TokenCheckFilter implements GlobalFilter, Ordered {
    /**
     * 制定好放行的路径
     * */
    public static final List<String> ALLOW_URL = Arrays.asList("/login-service/doLogin","/doLogin");

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /**
         * 一般和前端约定好 一般把token放在请求头里面 一般key为Authorization (授权的意思) value 为bearer token
         * 拿到请求url判断是否为登录url是就放行,不是继续操作
         * 拿到请求头
         * 拿到token
         * 校验
         * 放行/拦截
         * */
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        if(ALLOW_URL.contains(path)){
            return chain.filter(exchange);
        }
        //检查
        HttpHeaders headers = request.getHeaders();
        List<String> authorization = headers.get("Authorization");
        if(!CollectionUtils.isEmpty(authorization)){
            //如果authorization集合不为空
            //获取第一个为token
            String token = authorization.get(0);
            //判断给token里面的值是不是空字符串
            if(StringUtils.hasText(token)){
                //不为空
                //约定好的有前缀的bearer token
                String realToken = token.replaceFirst("bearer ","");
                //判断realToken是否为空以及redis数据库是否包含
                if(StringUtils.hasText(realToken)&&redisTemplate.hasKey(realToken)){
                    return chain.filter(exchange);
                }
            }
        }
        //如果不符合就不给访问
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().set("content-type","application/json;charset=utf-8");
        HashMap<String,Object> map = new HashMap<>(4);
        //返回401
        map.put("code", HttpStatus.UNAUTHORIZED.value());
        map.put("msg","未授权");
        ObjectMapper objectMapper = new ObjectMapper();
        byte [] bytes = new byte[0];
        try {
            bytes=objectMapper.writeValueAsBytes(map);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        DataBuffer wrap = response.bufferFactory().wrap(bytes);
        return response.writeWith(Mono.just(wrap));
    }

    @Override
    public int getOrder() {
    //配置优先级 越小越先执行
        return -1;
    }
}
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Spring Cloud Gateway是一个轻量级的网关框架,它可以作为微服务架构中的入口,实现代理和路由功能。在进行身份验证和授权时,可以使用Token进行安全验证。 Token是一种令牌,通常由后端服务颁发给客户端,用于验证客户端的身份和权限。在Spring Cloud Gateway使用Token可以通过以下方式实现: 1. 首先,客户端在请求头中携带Token,可以使用常见的认证方案,如Bearer Token。在路由的配置文件中,可以通过添加过滤器来获取请求头中的Token,并进行验证。 2. 在网关层,可以编写自定义的GlobalFilter过滤器,在请求到达后执行Token的验证逻辑。可以通过解析Token的信息,比如用户名、角色等,来进行用户身份验证和授权操作。 3. 在网关层,还可以使用Spring Security进行身份验证和授权。Spring Security提供了丰富的特性,如基于角色的访问控制、加密解密等。可以通过配置Spring Security的过滤器链来实现Token验证的功能。 使用Token进行安全验证的好处是,可以将验证逻辑移到网关层,使后端服务更加专注于业务逻辑的实现Token使用可以提供更高的灵活性和安全性,保护后端服务免受未经授权的访问。 总之,Spring Cloud Gateway可以通过添加过滤器、编写GlobalFilter过滤器或使用Spring Security来实现Token的安全验证。这样可以保护后端服务,确保只有经过身份验证和授权的客户端能够访问服务。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leach爱喝星冰乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值