尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
SpringCloud Gateway与Sa-Token实现微服务统一鉴权
1. 项目概述SpringCloud Alibaba Gateway与Sa-Token的登录鉴权整合在微服务架构中API网关作为系统入口承担着流量调度和安全防护的双重职责。传统方案中我们常使用Spring Security进行鉴权但其配置复杂度让不少开发者望而生畏。Sa-Token作为一款轻量级Java权限认证框架以注解式鉴权为核心设计理念与SpringCloud Gateway的结合能显著降低统一认证的实现门槛。这次我们要构建的鉴权流程包含三个关键组件Gateway服务作为所有请求的入口负责路由转发和全局过滤Auth服务基于Sa-Token实现登录认证和令牌签发Product服务受保护的资源服务通过注解校验权限提示本方案采用Redis作为会话存储介质确保分布式环境下的会话一致性。实际部署时请确保Redis服务可用。2. 环境准备与基础配置2.1 项目结构规划建议采用以下模块划分springcloud-alibaba ├── gateway-service # 网关模块 ├── auth-service # 认证中心 └── product-service # 资源服务2.2 依赖管理各模块需引入的关键依赖Gateway模块dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId /dependency dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-starter-gateway/artifactId /dependency dependency groupIdcn.dev33/groupId artifactIdsa-token-reactor-spring-boot-starter/artifactId version1.34.0/version /dependencyAuth模块dependency groupIdcn.dev33/groupId artifactIdsa-token-spring-boot-starter/artifactId version1.34.0/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency3. 认证中心实现细节3.1 认证核心配置在auth-service中配置application.ymlserver: port: 8101 spring: application: name: service-auth redis: host: 127.0.0.1 port: 6379 timeout: 10s lettuce: pool: max-active: 200 max-idle: 10 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/auth_db?useSSLfalse username: root password: 123456 cloud: nacos: discovery: server-addr: localhost:88483.2 登录接口实现创建AuthController处理认证逻辑RestController RequestMapping(/user) public class AuthController { PostMapping(/doLogin) public JsonResult doLogin(String username, String password) { // 模拟数据库校验 if(zhang.equals(username) 123456.equals(password)){ StpUtil.login(10001); return JsonResult.success(登录成功, StpUtil.getTokenInfo()); } return JsonResult.fail(登录失败); } SaCheckLogin GetMapping(/checkLogin) public JsonResult checkLogin() { return JsonResult.success(已登录, StpUtil.getLoginId()); } }4. 网关层关键实现4.1 全局过滤器配置创建GatewayAuthFilter实现登录校验Component public class GatewayAuthFilter implements GlobalFilter, Ordered { private static final ListString WHITE_LIST Arrays.asList( /auth/user/doLogin, /product-serv/product/list ); Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request exchange.getRequest(); String path request.getURI().getPath(); // 白名单直接放行 if(WHITE_LIST.contains(path)){ return chain.filter(exchange); } // 校验Token有效性 try { String token request.getHeaders().getFirst(Authorization); if(StringUtils.isEmpty(token) || !StpUtil.checkToken(token)){ return unauthorizedResponse(exchange); } return chain.filter(exchange); } catch (Exception e) { return unauthorizedResponse(exchange); } } private MonoVoid unauthorizedResponse(ServerWebExchange exchange) { ServerHttpResponse response exchange.getResponse(); response.setStatusCode(HttpStatus.UNAUTHORIZED); response.getHeaders().add(Content-Type, application/json); return response.writeWith(Mono.just(response.bufferFactory() .wrap(JsonResult.fail(请先登录).toString().getBytes()))); } Override public int getOrder() { return -100; } }4.2 路由配置示例gateway-service的application.ymlspring: cloud: gateway: routes: - id: auth-service uri: lb://service-auth predicates: - Path/auth/** - id: product-service uri: lb://service-product predicates: - Path/product-serv/**5. 资源服务保护方案5.1 注解式权限控制在product-service的Controller中使用Sa-Token注解RestController RequestMapping(/product) public class ProductController { SaCheckLogin GetMapping(/{id}) public Product getById(PathVariable Long id) { // 业务逻辑 } SaCheckRole(admin) PostMapping public Product create(RequestBody Product product) { // 创建逻辑 } }5.2 会话存储验证登录成功后可在Redis中看到类似数据结构sa-token:login:session:10001 - {tokenValue:xxxxx,loginId:10001} sa-token:login:token:xxxxx - 100016. 全链路测试流程6.1 未登录访问测试直接请求商品详情接口GET http://localhost:7000/product-serv/product/1应收到401响应{code:401,msg:请先登录,data:null}6.2 登录流程测试调用登录接口POST http://localhost:7000/auth/user/doLogin?usernamezhangpassword123456响应示例{ code:200, msg:登录成功, data:{ tokenName:satoken, tokenValue:xxxxx, isLogin:true, loginId:10001 } }6.3 已登录访问测试携带Token访问商品接口GET http://localhost:7000/product-serv/product/1 Authorization: satoken xxxxx应正常返回商品数据7. 进阶配置与优化建议7.1 令牌自动续期配置在auth-service中添加配置Configuration public class SaTokenConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new SaInterceptor()) .addPathPatterns(/**) .excludePathPatterns(/user/doLogin); } PostConstruct public void setSaTokenConfig() { // 令牌有效期30分钟最后5分钟自动续期 SaManager.getConfig() .setTimeout(60 * 30) .setActivityTimeout(60 * 25); } }7.2 微服务间鉴权方案对于服务间调用推荐使用Feign拦截器传递TokenBean public RequestInterceptor requestInterceptor() { return template - { String token StpUtil.getTokenValue(); if(StringUtils.isNotBlank(token)){ template.header(Authorization, satoken token); } }; }8. 常见问题排查指南问题现象可能原因解决方案502 Bad Gateway网关路由配置错误或下游服务不可用检查Nacos服务注册状态验证URI配置401 UnauthorizedToken缺失或失效检查请求头是否携带正确Token验证Redis连接403 Forbidden权限不足检查SaCheckRole注解配置的角色要求跨域问题网关未配置CORS在网关添加CORS过滤器重要提示当出现Token失效但Redis中仍存在会话数据时检查服务器时钟是否同步时差超过3分钟会导致Token校验失败9. 性能优化实践9.1 二级缓存配置在高并发场景下可启用内存缓存减少Redis访问sa-token: is-share: false # 关闭Cookie共享 token-style: uuid # Token生成策略 is-concurrent: true # 开启并发登录 is-share: false is-read-body: false is-read-head: true is-v: false jwt-secret-key: your-secret-key cache: type: redis # 启用二级缓存 second-cache-enable: true second-cache-timeout: 609.2 网关层优化启用响应缓存减少重复鉴权对静态资源路由启用缓存控制头限制频繁登录请求的IPBean public RedisRateLimiter redisRateLimiter() { return new RedisRateLimiter(10, 20); } Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route(auth-rate-limit, r - r.path(/auth/**) .filters(f - f.requestRateLimiter(c - c.setRateLimiter(redisRateLimiter()))) .uri(lb://service-auth)) .build(); }在微服务架构演进过程中网关鉴权方案的选择直接影响系统的安全性和开发效率。经过多个项目的实践验证Sa-Token与SpringCloud Gateway的组合在实现成本、维护复杂度和性能表现上达到了较好的平衡。特别是在快速迭代的业务场景中其注解式开发模式能让团队更专注于业务逻辑实现。
RELATED

相关推荐

Quill.js Delta 格式解析与富文本编辑实践

Quill.js Delta 格式解析与富文本编辑实践

1. Delta 文档结构解析:Quill.js 的核心设计哲学Delta 是 Quill.js 富文本编辑器独创的文档描述格式,它从根本上解决了传统富文本编辑器依赖 HTML 带来的诸多痛点。与常规 JSON 数据结构不同,Delta 采用操作序列(ops)来…

📅 2026/8/11 7:01:27
AI拆书与仿写实战:从框架解析到模式复用的创作指南

AI拆书与仿写实战:从框架解析到模式复用的创作指南

你有没有试过面对一本厚厚的书,想提炼出核心框架却无从下手?或者想写一个长篇故事,却卡在情节设计和人物塑造上?最近我花了一周时间,把市面上几个主流的大模型工具都试了一遍,重点测试了它们在拆书和仿写方…

📅 2026/8/12 5:22:49
那个一路走来,没有放弃自己的自己。

那个一路走来,没有放弃自己的自己。

人生最值得感谢的人,往往不是某个外部的人,而是那个在无数次想放弃的时候,依然带着你走到今天的自己。很多时候,我们只看见: “我还没有成为理想中的自己。” 却忘记:“曾经那个并不完美的自己,…

📅 2026/8/11 22:21:30
MORE NEWS

更多资讯

📰

Kubernetes GPU调度全解析:从驱动、容器运行时到Device Plugin

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

龙虾消费热潮背后的技术驱动与社会心理分析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Sunshine 游戏串流主机免费上手指南:30 分钟串出第一帧画面

Sunshine 游戏串流主机免费上手指南:30 分钟串出第一帧画面 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine 是一款自托管游戏串流主机,装在主机上…

📰

OCRmyPDF 教程:一分钟给扫描 PDF 加可搜索文字层

OCRmyPDF 教程:一分钟给扫描 PDF 加可搜索文字层 【免费下载链接】OCRmyPDF OCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched 项目地址: https://gitcode.com/GitHub_Trending/oc/OCRmyPDF 扫描件最大的尴尬在于&#…

📰

NautilusTrader 问题排查指南:3 步定位回测安装失败与“无交易“策略

NautilusTrader 问题排查指南:3 步定位回测安装失败与"无交易"策略 【免费下载链接】nautilus_trader Production-grade Rust-native trading engine with deterministic event-driven architecture 项目地址: https://gitcode.com/GitHub_Trending/na/…

📰

go2rtc 入门教程:5 分钟搭建低延迟摄像头流媒体服务器

go2rtc 入门教程:5 分钟搭建低延迟摄像头流媒体服务器 【免费下载链接】go2rtc Ultimate camera streaming application 项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc go2rtc 是一个用 Go 编写的零依赖摄像头串流应用,能把 RTSP、RT…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬