You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Gateway过滤器如何高效拦截已封禁用户的未过期JWT?

Spring Cloud Gateway 账号封禁实时拦截解决方案

方案1:本地缓存 + 状态变更事件推送(性能最优)

  • 实现逻辑:
    1. 用户微服务侧新增账号状态变更事件触发逻辑,用户封禁/解封操作完成后,将用户ID、最新状态推送到MQ(Kafka/RabbitMQ均可)
    2. 所有网关实例开启MQ广播消费模式,收到状态变更事件后更新本地Caffeine缓存,仅存储状态异常的用户ID即可,正常状态用户无需存入缓存节省空间
    3. 网关JWT校验过滤器中,解析出用户ID后仅需查询本地缓存,存在记录则直接返回UNAUTHORIZED,无记录直接放行
  • 性能表现:本地缓存查询为纳秒级,无任何远程调用开销,仅在用户状态变更时产生极少量MQ消息开销,对业务接口无性能影响
  • 代码示例(本地缓存配置):
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;

@Configuration
public class BannedUserCacheConfig {
    @Bean
    public Cache<Long, Boolean> bannedUserCache() {
        return Caffeine.newBuilder()
                // 可根据实际封禁用户规模调整最大值
                .maximumSize(10000)
                // 兜底过期时间,避免消息丢失导致脏数据
                .expireAfterWrite(24, TimeUnit.HOURS)
                .build();
    }
}

方案2:分布式缓存 + 短周期本地缓存(一致性优先)

  • 实现逻辑:
    1. 用Redis存储全量封禁用户ID集合,用户状态变更时同步更新Redis数据,设置7天过期时间,后台定时任务每24小时全量同步一次封禁用户列表兜底
    2. 网关层新增10秒周期的本地二级缓存,同一个用户的请求10秒内仅查询1次Redis,大幅降低Redis访问压力
    3. 过滤器中优先查本地二级缓存,未命中再查Redis,存在封禁记录则拦截
  • 适用场景:网关实例数量多、不方便部署MQ广播消费的场景,数据一致性比纯本地缓存更高,Redis查询性能可达万级QPS,完全满足网关流量需求

方案3:JWT版本号机制(通用型失效方案)

  • 实现逻辑:
    1. 生成JWT时在payload中新增user_version字段,用户状态/权限等核心信息变更时,将对应用户的版本号+1存储到Redis/用户表
    2. 网关校验JWT时,对比JWT携带的版本号与缓存中存储的最新版本号,不一致则直接拦截
    3. 同样可叠加本地短周期缓存优化版本号查询性能
  • 优势:可覆盖所有需要JWT主动失效的场景,包括账号封禁、权限变更、密码修改、强制下线等,扩展性更强

兜底降级策略

如果MQ/Redis等中间件故障,网关可降级为每5分钟主动拉取一次全量封禁用户列表存储到本地,保证基础拦截能力不会失效。

内容的提问来源于stack exchange,提问作者user13548798

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:15:00