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 或配置中心
相关推荐
梵得儿SHI7 天前
SpringCloud 生产级落地:Docker 容器化 + K8s 编排部署全攻略(含完整 yaml + 避坑指南)
docker·云原生·kubernetes·k8s·springcloud·微服务部署·java 后端
甜鲸鱼8 天前
JWT过滤器:从单体应用到微服务架构
微服务·架构·gateway·springcloud
notfound40438 天前
解决SpringCloudGateway用户请求超时导致日志未记录情况
java·spring boot·spring·gateway·springcloud
8Qi813 天前
Elasticsearch实战篇:索引库、文档与JavaRestClient操作指南
java·大数据·elasticsearch·搜索引擎·微服务·架构·springcloud
8Qi816 天前
RabbitMQ高级篇:消息可靠性、幂等性与延迟消息
java·分布式·微服务·中间件·rabbitmq·springcloud
代码漫谈16 天前
微服务 vs 单体架构:架构选型、实战拆解与决策指南
java·微服务·springboot·springcloud
色空大师17 天前
【微服务项目-短信平台】
java·redis·微服务·rabbitmq·springcloud·短信
梵得儿SHI17 天前
SpringCloud 实战落地:可观测性建设(SkyWalking + Prometheus + Grafana)从 0 到 1 生产级部署
grafana·prometheus·springcloud·skywalking·微服务可观测性·线上问题排查
鬼先生_sir20 天前
Dubbo:从入门到精通
java·dubbo·springcloud
鬼先生_sir21 天前
SpringCloud Seata 四大模式(AT/TCC/SAGA/XA)全解析
seata·springcloud·分布式事务