首页 > 其他分享 >网关登录校验

网关登录校验

时间:2024-07-26 20:53:20浏览次数:14  
标签:网关 return 登录 校验 springframework token org import

网关登录校验

首先写一个demo

package com.hmall.gateway.filter;


import com.hmall.gateway.config.AuthProperties;
import com.hmall.gateway.util.JwtTool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
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.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


import java.util.List;

/**
 * @Order(0) 和 实现Ordered接口一样
 */


@Slf4j
@Component
//@Order(0)
@RequiredArgsConstructor
public class AutoGlobalFilter implements GlobalFilter, Ordered {


    private final AuthProperties authProperties;

    private final JwtTool jwtTool;

    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1. 获取request对象
        ServerHttpRequest request = exchange.getRequest();
        //2. 判断是否需要拦截校验
        if (isExclude(request.getPath().toString())) {   //判断这个路径要不要拦截
            //放行
            return chain.filter(exchange);
        }
        //3. 获取请求头中 jwt令牌 Authorization
        String authorization = request.getHeaders().getFirst("Authorization");
        //4. 解析令牌 并校验
        Long userId = null;
        try {
            userId = jwtTool.parseToken(authorization);
        } catch (Exception e) {
            log.error("解析令牌失败", e);
            //设置响应状态码
            ServerHttpResponse response = exchange.getResponse();
            //401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        //5. 如果有效 将传递信息给后台
        System.out.println("userId = " + userId);
        String userIdStr = userId.toString();
        ServerWebExchange swe = exchange.mutate()
                .request(builder -> builder.header("user-info", userIdStr))
                .build();
        //6. 放行
        return chain.filter(swe);
    }

    /**
     * 校验方法
     *
     * @param path
     * @return
     */
    private boolean isExclude(String path) {
        //获取排除的路径
        List<String> excludePaths = authProperties.getExcludePaths();
        for (String excludePath : excludePaths) {
            //做校验
            if (antPathMatcher.match(excludePath, path)) {
                //匹配返回true
                return true;
            }
        }
        return false;
    }


    @Override
    public int getOrder() {
        return 0;
    }
}

![登录校验的流程如图](https://i-blog.csdnimg.cn/direct/1bd1e33f5a374ea78130e838bdacefd4.png#pic_center)

AuthProperties实体类

package com.hmall.gateway.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;

@Data
@Component
@ConfigurationProperties(prefix = "hm.auth")
public class AuthProperties {
    private List<String> includePaths;
    private List<String> excludePaths;
}

JwtTool 工具类 进行一系列的校验

package com.hmall.gateway.util;

import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.hmall.common.exception.UnauthorizedException;
import org.springframework.stereotype.Component;

import java.security.KeyPair;
import java.time.Duration;
import java.util.Date;

@Component
public class JwtTool {
    private final JWTSigner jwtSigner;

    public JwtTool(KeyPair keyPair) {
        this.jwtSigner = JWTSignerUtil.createSigner("rs256", keyPair);
    }

    /**
     * 创建 access-token
     *
     * @param userId 用户信息
     * @return access-token
     */
    public String createToken(Long userId, Duration ttl) {
        // 1.生成jws
        return JWT.create()
                .setPayload("user", userId)
                .setExpiresAt(new Date(System.currentTimeMillis() + ttl.toMillis()))
                .setSigner(jwtSigner)
                .sign();
    }

    /**
     * 解析token
     *
     * @param token token
     * @return 解析刷新token得到的用户信息
     */
    public Long parseToken(String token) {
        // 1.校验token是否为空
        if (token == null) {
            throw new UnauthorizedException("未登录");
        }
        // 2.校验并解析jwt
        JWT jwt;
        try {
            jwt = JWT.of(token).setSigner(jwtSigner);
        } catch (Exception e) {
            throw new UnauthorizedException("无效的token", e);
        }
        // 2.校验jwt是否有效
        if (!jwt.verify()) {
            // 验证失败
            throw new UnauthorizedException("无效的token");
        }
        // 3.校验是否过期
        try {
            JWTValidator.of(jwt).validateDate();
        } catch (ValidateException e) {
            throw new UnauthorizedException("token已经过期");
        }
        // 4.数据格式校验
        Object userPayload = jwt.getPayload("user");
        if (userPayload == null) {
            // 数据为空
            throw new UnauthorizedException("无效的token");
        }

        // 5.数据解析
        try {
           return Long.valueOf(userPayload.toString());
        } catch (RuntimeException e) {
            // 数据格式有误
            throw new UnauthorizedException("无效的token");
        }
    }
}

登录校验过滤器 最后结果

package com.hmall.gateway.filter;


import com.hmall.gateway.config.AuthProperties;
import com.hmall.gateway.util.JwtTool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
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.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


import java.util.List;

/**
 * @Order(0) 和 实现Ordered接口一样
 */


@Slf4j
@Component
//@Order(0)
@RequiredArgsConstructor
public class AutoGlobalFilter implements GlobalFilter, Ordered {


    private final AuthProperties authProperties;

    private final JwtTool jwtTool;

    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1. 获取request对象
        ServerHttpRequest request = exchange.getRequest();
        //2. 判断是否需要拦截校验
        if (isExclude(request.getPath().toString())) {   //判断这个路径要不要拦截
            //放行
            return chain.filter(exchange);
        }
        //3. 获取请求头中 jwt令牌 Authorization
        String authorization = request.getHeaders().getFirst("Authorization");
        //4. 解析令牌 并校验
        Long userId = null;
        try {
            userId = jwtTool.parseToken(authorization);
        } catch (Exception e) {
            log.error("解析令牌失败", e);
            //设置响应状态码
            ServerHttpResponse response = exchange.getResponse();
            //401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        //5. 如果有效 将传递信息给后台
        System.out.println("userId = " + userId);
        String userIdStr = userId.toString();
        ServerWebExchange swe = exchange.mutate()
                .request(builder -> builder.header("user-info", userIdStr))
                .build();
        //6. 放行
        return chain.filter(swe);
    }

    /**
     * 校验方法
     *
     * @param path
     * @return
     */
    private boolean isExclude(String path) {
        //获取排除的路径
        List<String> excludePaths = authProperties.getExcludePaths();
        for (String excludePath : excludePaths) {
            //做校验
            if (antPathMatcher.match(excludePath, path)) {
                //匹配返回true
                return true;
            }
        }
        return false;
    }


    @Override
    public int getOrder() {
        return 0;
    }
}

注意点:
@RequiredArgsConstructor // 可以不用加@Autowired注解
private final AntPathMatcher antPathMatcher = new AntPathMatcher(); 需要new出来

标签:网关,return,登录,校验,springframework,token,org,import
From: https://blog.csdn.net/2301_79452138/article/details/140724527

相关文章

  • 软考-软件设计师(1)-计算机基础知识点:进制转换、数据编码、内存编址、串并联可靠性、
    场景软考-软件设计师-计算机基础模块高频考点整理。以下为高频考点、知识点汇总,不代表该模块所有知识点覆盖,请以官方教程提纲为准。注:博客:霸道流氓气质-CSDN博客实现知识点进制转换十进制转二进制除以2,反向取余数,直到商为0终止,转换成其他进制同理二进制转十进制其......
  • 一条命令搞定WPS免登录,轻松省时又省力!
    文章目录......
  • 高速上用到的视频上云网关现在市场上真的太卷了
      先看一个需求: 这个是最近的一个招标项目上对视频网关的需求,我看了以后,真的有点不知道该怎么说。两个问题:第一个问题,目前都在执行新标准了,部标目前是128K推送到标准了,这个招标文件中还是32K,看来设计公司这个项目时,还是去年上半年的时候,但这个标发出来前,难道不应该......
  • 宏集物联网工控屏&网关实现Modbus TCP数据采集并通过TCP转发
    前言在日常的生产活动中,许多企业需要使用底层PLC或传感器数据,但部分企业的终端平台仅支持TCP协议,而不支持常见的PLC或Modbus协议。为了实现兼容性,需要使用协议转换网关,将底层协议转换为TCP协议。宏集物联网工控屏&网关支持200多种通信协议,包括常见的ModbusRTU/TCP、OPCUA,以......
  • 无密码登录
    需求机器A(客户端)使用SSH免密连接机器B(服务端)客户端配置进入用户目录的.ssh目录,生成公钥和私钥ssh-keygen-trsa在执行的过程中,一路回车,不要修改任何东西。全部默认将生成的公钥分发到服务端方法一:使用ssh-copy-id命令,将公钥添加到服务端的authorized_keys文......
  • BGP(Border Gateway Protocol,边界网关协议)劫持是指恶意或非法地篡改BGP路由信息的行为
    BGP(BorderGatewayProtocol,边界网关协议)劫持是指恶意或非法地篡改BGP路由信息的行为。BGP是互联网上用来交换路由信息的主要协议之一,它负责决定网络数据包应该如何从一个网络路由到另一个网络。BGP劫持可以分为两种主要类型:前缀劫持(PrefixHijacking):在前缀劫持中,攻击者发送......
  • Harmony鸿蒙实战开发-记事本「登录保护」【源码在文末】
    Harmony鸿蒙实战开发-记事本「登录保护」【源码在文末】文章目录Harmony鸿蒙实战开发-记事本「登录保护」【源码在文末】一、运行演示1、注册2、登录3、主页4、编写二、部分代码三、源码运行工具:DevEcoStudio一、运行演示1、注册2、登录3、主页4、编写......
  • Profinet转ModbusTCP网关模块的配置与应用详解
    Profinet转ModbusTCP网关模块的配置与应用详解Profinet转ModbusTCP网关模块(XD-ETHPN20)是一种常见的工业通信设备,广泛应用于现代工业自动化系统中。通过使用Profinet转ModbusTCP网关模块(XD-ETHPN20)将Profinet协议转换成ModbusTCP协议,实现了不同网络之间的互联互通。这种网关设备......
  • 流量回放新形态:基于网关 Access Log 发起
    作者:休祯背景为什么需要流量回放无论是面向即将上线的新版本做最后的性能测试,还是在遇到棘手的故障时帮助开发人员快速定位问题原因,流量回放技术都发挥着不可或缺的作用。使用真实世界的流量数据进行回放能使性能测试过程更加接近实际运行状态,确保新版本的性能真正满足用户的预......
  • Easyconnect登录提示:拉起虚拟网卡失败 解决办法
    原文链接:https://www.cnblogs.com/runningwind/p/17532438.html用户使用easyconnect登录SSLVPN后提示:拉起虚拟网卡失败,请确保虚拟网卡已经安装在系统上并处于启用状态 设备管理器查看虚拟网卡一直有感叹号 尝试更新网卡驱动及启用禁用虚拟网卡,不行尝试使用SSLVPN诊断修......