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 或配置中心
相关推荐
鬼先生_sir12 小时前
SpringCloud Seata 四大模式(AT/TCC/SAGA/XA)全解析
seata·springcloud·分布式事务
leo_messi948 天前
2026版商城项目(二)-- 压力测试&缓存
java·缓存·压力测试·springcloud
總鑽風9 天前
springcloud2023_alibaba_sso单点登录_授权码模式(已跑通)
springcloud·单点登录·sso·授权码模式
總鑽風10 天前
springcloudalibaba2021-SSO 单点登录_密码模式
springcloud·alibaba·sso
奥升新能源平台13 天前
奥升充电最小化高可用机房部署方案
运维·安全·开源·能源·springcloud
leo_messi9416 天前
2026版商城项目(一)
java·elasticsearch·k8s·springcloud
没有bug.的程序员17 天前
S 级 SaaS 平台的物理雪崩:Spring Cloud Gateway 多租户动态路由与 UserID 极限分片
java·gateway·springboot·saas·springcloud·多租户、·userid
Dragon Wu2 个月前
SpringCache 缓存使用总结
spring boot·后端·spring·缓存·springcloud
七夜zippoe2 个月前
微服务链路追踪实战:SkyWalking vs Zipkin 架构深度解析与性能优化指南
java·开发语言·微服务·springcloud·sleuth·zipkin
梦想总是可以实现的2 个月前
SpringCloud2024 + JDK17实战:手把手教你从零搭建微服务全家桶(含Eureka+Gateway+Redis)
springcloud·微服务架构·java开发·分布式系统