首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >统一网关的登录流程总结

统一网关的登录流程总结

作者头像
SmileNicky
发布2026-03-10 08:07:33
发布2026-03-10 08:07:33
1650
举报
文章被收录于专栏:Nicky's blogNicky's blog

统一网关登录流程的面试要点,这是微服务架构中非常核心的高频考点。


🏗️ 整体架构图

代码语言:javascript
复制
┌─────────────┐      ┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│   客户端     │      │  API Gateway │      │  认证中心    │      │  下游微服务  │
│ (Web/App)   │◄────►│   (统一网关)  │◄────►│ (Auth Server)│◄────►│ (业务服务)   │
└─────────────┘      └─────────────┘      └─────────────┘      └─────────────┘
                            │
                      ┌─────┴─────┐
                      │   Redis   │  ← Token黑名单/会话缓存
                      └───────────┘

🔐 核心登录流程(3种主流模式)

模式一:网关集中式认证(最常用)

流程步骤

  1. 用户登录 → 请求网关 /auth/login → 转发到认证中心
  2. 身份验证 → 认证中心校验用户名密码 → 生成 JWT Token(Access Token + Refresh Token)
  3. Token返回 → 网关返回 Token 给客户端
  4. 业务请求 → 客户端携带 Authorization: Bearer <token> 请求网关
  5. 统一鉴权 → 网关全局过滤器校验 JWT(签名、过期时间)
  6. 身份传递 → 网关将用户信息(UserID、Roles)写入请求头,转发给下游服务
  7. 业务处理 → 下游服务根据请求头中的用户信息进行权限判断和业务处理

核心代码(Spring Cloud Gateway):

代码语言:javascript
复制
@Component
@Order(-1) // 最高优先级执行
public class JwtAuthenticationFilter implements GlobalFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().value();
        
        // 1. 白名单放行(登录、注册、健康检查)
        if (isPublicPath(path)) {
            return chain.filter(exchange);
        }
        
        // 2. 提取 Token
        String token = extractToken(request);
        if (token == null) {
            return unauthorized(exchange, "缺少Token");
        }
        
        // 3. 校验 Token(签名、过期时间、黑名单)
        try {
            DecodedJWT jwt = JWTVerifier.verify(token);
            
            // 4. 将用户信息传递给下游服务
            ServerHttpRequest mutatedRequest = exchange.getRequest().mutate()
                .header("X-User-Id", jwt.getSubject())
                .header("X-User-Roles", jwt.getClaim("roles").asString())
                .header("X-User-Name", jwt.getClaim("username").asString())
                .build();
                
            return chain.filter(exchange.mutate().request(mutatedRequest).build());
            
        } catch (TokenExpiredException e) {
            return unauthorized(exchange, "Token已过期");
        } catch (JWTVerificationException e) {
            return unauthorized(exchange, "Token无效");
        }
    }
}

模式二:OAuth2 + JWT 授权码模式(第三方登录场景)

流程步骤

  1. 授权请求 → 客户端重定向到认证中心 /oauth2/authorize
  2. 用户登录 → 用户在认证中心完成登录并授权
  3. 授权码返回 → 认证中心返回 Authorization Code 给客户端
  4. 换取Token → 客户端携带 Code 请求网关 /oauth2/token
  5. 颁发Token → 网关返回 Access Token(JWT)+ Refresh Token(Opaque Token)
  6. 后续请求 → 同模式一,网关统一校验 JWT

Token 类型区别

Token 类型

格式

有效期

用途

Access Token

JWT(自包含)

短(15-30分钟)

访问资源

Refresh Token

Opaque(随机串)

长(7-30天)

刷新 Access Token

ID Token

JWT

同 Access Token

包含用户基本信息(OIDC)


模式三:Session + Cookie 模式(传统 Web 场景)

流程步骤

  1. 用户登录 → 网关验证凭证后创建 Session,存储在 Redis
  2. Cookie返回 → 网关设置 Set-Cookie: SESSION_ID=xxx 给浏览器
  3. 后续请求 → 浏览器自动携带 Cookie,网关从 Redis 查询 Session 获取用户信息
  4. 信息传递 → 网关将用户信息写入请求头转发

适用场景:传统服务端渲染 Web 应用,需要服务端控制会话状态


🛡️ 面试必问:网关统一认证 vs 服务自认证

维度

网关统一认证(推荐)

各服务自认证

安全性

统一安全策略,所有请求必须过网关

容易遗漏,策略不一致

性能

避免无效请求进入内网

重复解析 JWT,浪费资源

开发成本

服务无感知,专注业务

每个服务都要实现认证逻辑

灵活性

需要网关支持自定义规则

各服务可定制

运维复杂度

日志集中,便于审计

日志分散,难以追踪

面试金句“网关统一认证实现了认证边界的内移,在架构入口处建立单一可信边界,符合零信任架构的’永不信任,始终验证’原则”


🔄 Token 刷新机制(双 Token 策略)

为什么需要刷新?

  • Access Token 有效期短(15分钟),降低泄露风险
  • Refresh Token 有效期长(7天),但只用于换 Token,不直接访问资源

刷新流程

代码语言:javascript
复制
// 伪代码:网关过滤器中实现 Token 自动刷新
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    String accessToken = extractToken(request);
    
    try {
        verifyToken(accessToken);
        return chain.filter(exchange);
    } catch (TokenExpiredException e) {
        // Token 过期,尝试用 Refresh Token 刷新
        String refreshToken = extractRefreshToken(request);
        
        if (refreshToken != null && validateRefreshToken(refreshToken)) {
            // 生成新 Access Token
            String newAccessToken = generateNewToken(refreshToken);
            
            // 返回新 Token(通过 Response Header 或 Body)
            exchange.getResponse().getHeaders().add("X-New-Token", newAccessToken);
            
            // 继续处理当前请求
            return chain.filter(exchange);
        } else {
            return unauthorized(exchange, "登录已过期,请重新登录");
        }
    }
}

🚨 安全加固要点(面试加分项)

1. Token 黑名单机制(主动登出)
代码语言:javascript
复制
@Service
public class TokenBlacklistService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    // 登出时将 Token 加入黑名单(TTL 设为 Token 剩余有效期)
    public void addToBlacklist(String token, long expirationTime) {
        String jti = JWT.decode(token).getId(); // JWT ID
        long ttl = expirationTime - System.currentTimeMillis();
        redisTemplate.opsForValue().set("blacklist:" + jti, "1", ttl, TimeUnit.MILLISECONDS);
    }
    
    public boolean isBlacklisted(String token) {
        String jti = JWT.decode(token).getId();
        return redisTemplate.hasKey("blacklist:" + jti);
    }
}
2. 关键安全策略

策略

实现方式

HTTPS 强制

网关层强制 HSTS,拒绝 HTTP 请求

Token 存储

Access Token 存内存(Redux/Vuex),Refresh Token 存 HttpOnly Cookie

敏感操作二次认证

支付/修改密码等操作要求重新输入密码或短信验证

限流防刷

登录接口限流(如 5次/分钟),防止暴力破解

密钥轮换

定期更换 JWT 签名密钥,旧密钥保留一段时间用于验证旧 Token

3. 性能优化
代码语言:javascript
复制
// JWT 解析结果缓存(Caffeine)
@Component
public class JwtCacheManager {
    private final Cache<String, DecodedJWT> cache = Caffeine.newBuilder()
        .expireAfterWrite(5, TimeUnit.MINUTES)
        .maximumSize(10000)
        .build();
        
    public DecodedJWT verifyWithCache(String token) {
        return cache.get(token, t -> JWTVerifier.verify(t));
    }
}

💼 面试高频问题 & 标准答案

Q1:网关鉴权失败,如何设计降级策略?

:熔断降级设计:

  • 认证中心不可用时,网关允许已缓存的公钥继续验证 Token(JWT 自包含特性)
  • 极端情况下可降级为只限流不鉴权,保证核心业务可用
Q2:如何实现"踢人下线"功能?

:三种方案:

  1. Token 黑名单:登出时将 JTI(Token ID)存入 Redis,网关校验时检查
  2. 修改密钥:强制所有 Token 失效(影响所有用户,慎用)
  3. Session 模式:直接删除 Redis 中的 Session 记录
Q3:网关如何处理下游服务的权限细化?

:网关负责粗粒度认证(校验 Token 有效性),下游服务负责细粒度授权(判断用户是否有权操作某条数据)。网关传递用户角色/权限标识,服务内部做 RBAC/ABAC 判断 。

Q4:JWT 泄露了怎么办?

:短期泄露风险可控(Token 有效期短),长期:

  1. 立即将 Token 加入黑名单
  2. 轮换签名密钥
  3. 强制用户重新登录(清除 Refresh Token)

🎯 架构选型建议

场景

推荐方案

理由

纯内部微服务

网关 + JWT

无状态,性能好

涉及第三方登录

OAuth2 + JWT

标准协议,生态成熟

高安全要求金融场景

网关 + OAuth2 + mTLS

双向证书 + Token 双重验证

遗留系统改造

网关适配层

逐步迁移,兼容旧 Session

面试总结一句话“统一网关登录的核心是集中认证、分散授权——网关在入口处建立信任边界,通过无状态的 JWT 传递身份信息,既保证安全又实现服务间的解耦。”

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🏗️ 整体架构图
  • 🔐 核心登录流程(3种主流模式)
    • 模式一:网关集中式认证(最常用)
    • 模式二:OAuth2 + JWT 授权码模式(第三方登录场景)
    • 模式三:Session + Cookie 模式(传统 Web 场景)
  • 🛡️ 面试必问:网关统一认证 vs 服务自认证
  • 🔄 Token 刷新机制(双 Token 策略)
  • 🚨 安全加固要点(面试加分项)
    • 1. Token 黑名单机制(主动登出)
    • 2. 关键安全策略
    • 3. 性能优化
  • 💼 面试高频问题 & 标准答案
    • Q1:网关鉴权失败,如何设计降级策略?
    • Q2:如何实现"踢人下线"功能?
    • Q3:网关如何处理下游服务的权限细化?
    • Q4:JWT 泄露了怎么办?
  • 🎯 架构选型建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档