Spring Cloud Gateway 实现登录校验:构建统一认证入口

Spring Cloud Gateway 实现登录校验:构建统一认证入口

一、为什么需要在网关层进行登录校验?

🔒 遇到的实际问题:

  • 用户请求直接打到某个微服务,绕过了登录认证;
  • 每个服务都实现登录校验,代码冗余、安全隐患大;
  • 缺乏统一认证体系,权限边界模糊;
  • 无法集中管理黑名单、权限控制等安全规则。

✅ 网关统一登录校验的优势:

优点 说明
安全性高 所有请求必须经过网关,避免绕过
易于维护 登录校验逻辑集中处理
可扩展性强 支持多种认证方式,如 JWT、Session、OAuth2
支持 Token 鉴权 JWT 无状态、跨服务使用
降低服务耦合度 各服务只关注业务逻辑,不再处理认证

二、实战演示:Gateway + JWT 登录拦截实现

🔐 推荐方案:JWT(JSON Web Token)

  • 前端登录成功后,认证服务返回 JWT Token;
  • Token 存储在前端本地(localStorage / cookie);
  • 所有请求都在 Header 中携带 Token;
  • 网关拦截并解析 Token,验证其合法性;
  • 若合法则放行请求,否则返回 401 未授权。

1️⃣ 引入依赖

xml 复制代码
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

2️⃣ JWT 工具类

java 复制代码
public class JwtUtil {
    private static final String SECRET = "MySecretKey";

    public static Claims parseToken(String token) throws Exception {
        return Jwts.parser()
            .setSigningKey(SECRET.getBytes(StandardCharsets.UTF_8))
            .parseClaimsJws(token)
            .getBody();
    }

    public static boolean isExpired(Claims claims) {
        return claims.getExpiration().before(new Date());
    }
}

3️⃣ 编写网关登录过滤器(GlobalFilter)

java 复制代码
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    private static final List<String> whiteList = Arrays.asList(
        "/login", "/register", "/actuator/**"
    );

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getURI().getPath();

        // 白名单放行
        if (whiteList.stream().anyMatch(path::startsWith)) {
            return chain.filter(exchange);
        }

        // 获取 Authorization 头
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (StringUtils.hasText(token) && token.startsWith("Bearer ")) {
            token = token.replace("Bearer ", "");
            try {
                Claims claims = JwtUtil.parseToken(token);
                if (!JwtUtil.isExpired(claims)) {
                    // Token 有效,放行
                    return chain.filter(exchange);
                }
            } catch (Exception e) {
                // Token 非法或异常
            }
        }

        // 拦截并返回 401
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {
        return -100; // 优先级高
    }
}

4️⃣ 配置白名单和跨域支持(可选)

java 复制代码
@Configuration
public class CorsGlobalConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

三、常见问题与处理建议

问题 解决方案
前端跨域无法访问 Gateway 接口 配置 CORS
Token 解析失败或过期 返回 401 并提示重新登录
微服务之间需要用户信息 可通过请求头传递用户ID、角色等信息
白名单路径过多 可集中配置在 application.yml 或配置中心
相关推荐
DN金猿14 小时前
spring.cloud.nacos.discovery.server-addr和spring.cloud.nacos.server-addr区别
java·开发语言·nacos·springcloud·sca
DN金猿20 小时前
SpringCloudAlibaba微服务启动报错
微服务·云原生·nacos·架构·springcloud·sca
JAVA坚守者2 天前
Tomcat 多微服务部署:启动顺序 + JVM 调优实战
springcloud·jvm调优·权限问题·tomcat8.5·外置tomcat部署·启动顺序控制
豆沙沙包?3 天前
SpringCloud01-03---简介/从单体到集群架构/从单体到分布式架构
分布式·微服务·架构·springcloud
下次再写10 天前
深入浅出微服务架构:从理论到Spring Boot实战
java·微服务·springboot·springcloud·架构设计·后端开发·分布式系统
_waylau12 天前
“Java+AI全栈工程师”问答01:Spring MVC登录页面错误提示
java·开发语言·vue.js·后端·spring·mvc·springcloud
budingxiaomoli20 天前
环境和工程创建
java·spring·springcloud
budingxiaomoli20 天前
服务注册-服务实现
运维·springcloud
梵得儿SHI1 个月前
SpringCloud 生产级落地:Docker 容器化 + K8s 编排部署全攻略(含完整 yaml + 避坑指南)
docker·云原生·kubernetes·k8s·springcloud·微服务部署·java 后端
甜鲸鱼1 个月前
JWT过滤器:从单体应用到微服务架构
微服务·架构·gateway·springcloud