版本:

  • Springboot3.0.5以及对应的Springcloud,SpringcloudAlibaba依赖
  • nacos 2.2.0,sa-token1.34.0,Mysql8.0

前提:

  • 我这边是主要是对管理员进行鉴权的,所以划分了管理员以及网关服务,而sa-token的统一鉴权是在网关服务里面设计的。
  • Sa-token官方网址:Sa-Token

父依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><properties><java.version>17</java.version><!--        springboot 3 对应mybatis 3.0.0以上,否则会报错--><mybatis-spring-boot-starter.version>3.0.0</mybatis-spring-boot-starter.version><spring-cloud-alibaba.version>2022.0.0.0-RC1</spring-cloud-alibaba.version><spring.cloud.dependencies>2022.0.1</spring.cloud.dependencies></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) --><dependency><groupId>cn.dev33</groupId><artifactId>sa-token-dao-redis-jackson</artifactId><version>1.34.0</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis-spring-boot-starter.version}</version></dependency><!--springcloud alibaba--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!-- 这里引入最新的SpringCloud依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud.dependencies}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

Admin服务子模块

依赖

<dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.9</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!--        nacos 配置中心--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- 这里需要单独导入LoadBalancer依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!-- Sa-Token 权限认证(Reactor响应式集成), 在线文档:https://sa-token.cc --><dependency><groupId>cn.dev33</groupId><artifactId>sa-token-spring-boot3-starter</artifactId><version>1.34.0</version></dependency><!-- 自定义公共模块--><dependency><groupId>com.example</groupId><artifactId>commons</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>io.projectreactor</groupId><artifactId>reactor-core</artifactId><version>3.5.4</version></dependency></dependencies>

控制器类:按照官方文档,我们知道只需要实现它的StpUtil.login(Object id); 方法就行。

@RestController
@RequestMapping("/admin")
public class AdminController{@ResourceAdminService adminService;@PostMapping("/login")public R login(@RequestParam("id") int id,@RequestParam("password") String password){Admin admin=adminService.login(id,password);if(!ObjectUtils.isEmpty(admin)){
//            登录StpUtil1.setStpLogic(new StpLogic("admin"));StpUtil1.login(admin.getId());
//            获取token并返回return   R.success("登录成功",StpUtil1.getTokenInfo());}return R.error("登录失败");}

上面我用的是StpUtil1而不是StpUtil ,原因是我系统有两个角色超级管理员管理员,所以根据官方文档我创建了一个新的类,叫做StpUtil1,然后将其StpUtil复制过来,更改其属性TYPE为admin 。同理超级管理员也是创建多一个类就行,更改TYPE,这让我想起了设计模式的开闭原则哈哈哈。

配置文件bootstrap.yml,因为配置数据库的配置在配置中心,这里就不放出来了

Redis整合

这里sa-token整合redis只需要将配置文件配置,和导入依赖,sa-token就会自动将数据存入redis里面了,注意版本要对上,以防错误。

server:port: 8081
spring:application:name: Admin-serviceprofiles:# 环境也是和配置文件保持一致active: dbcloud:nacos:config:# 配置文件后缀名file-extension: yml# 配置中心服务器地址,也就是Nacos地址server-addr: localhost:8848prefix: dataBasediscovery:# 配置Nacos注册中心地址server-addr: localhost:8848data:# redis配置redis:# Redis数据库索引(默认为0)database: 1# Redis服务器地址host: 127.0.0.1# Redis服务器连接端口port: 6379# Redis服务器连接密码(默认为空)# password:# 连接超时时间timeout: 10slettuce:pool:# 连接池最大连接数max-active: 200# 连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: -1ms# 连接池中的最大空闲连接max-idle: 10# 连接池中的最小空闲连接min-idle: 0

Gateway服务子模块

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>competition</artifactId><groupId>com.example</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>GateWay</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><!--       网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>cn.dev33</groupId><artifactId>sa-token-reactor-spring-boot3-starter</artifactId><version>1.34.0</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--        一定要引入 loadbalancer才能使用 lb://进行负载均衡调用--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!--注册中心客户端--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--依赖冲突,通过该方法可以巧妙去除(重写覆盖,)父类依赖,这就是maven解决冲突的最短依赖路径原则。--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><scope>test</scope></dependency><!-- 自定义公共模块--><dependency><groupId>com.example</groupId><artifactId>commons</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies>
</project>

整合Gateway注意点

值得注意的是,因为Gateway是基于 WebFlux开发的,所以呢,我们需要去到官网,找一下下资料,如图,要导入的依赖是带有reactor的噢,而且因为使用的是springboot3,所以还要将boot改为boot3别导错依赖了!!

全局过滤器类(鉴权,登录拦截token,跨域)

  • SptUtil1和SptUtil2都是在公共模块commons中的哈,然后两者除了Type不一样其他都一样,用来区分不同管理员,超级管理员是拥有所有权限的,而管理员权限是超级管理员分配的。
  • 所以超级管理员只要登录就可以访问各个路径啦
  • 但是管理员就要检测一下权限了。看官网给出的详细代码解释
package com.test.conf;import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaHttpMethod;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.test.entity.StpUtil1;
import com.test.entity.StpUtil2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;/*** @author LiYa* @create 2023-04-05 22:36*/
@Configuration
public class SaTokenConfigure  {// 注册 Sa-Token全局过滤器@Bean@Primarypublic SaReactorFilter getSaReactorFilter() {return new SaReactorFilter  ()// 拦截地址.addInclude("/**")// 开放地址.addExclude("/admin/login").addExclude("/SuperAdmin/login")// 鉴权方法:每次访问进入.setAuth(obj -> {System.out.println("---------- sa全局认证");System.out.println(StpUtil1.isLogin());System.out.println(StpUtil2.isLogin());System.out.println(StpUtil1.getPermissionList());// 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
//                    SaRouter.match("/**", "/admin/login", r -> StpUtil1.checkLogin());// 角色认证 -- 拦截以 admin 开头的路由,必须具备 admin 角色或者 super-admin 角色才可以通过认证// 权限认证 -- 不同模块, 校验不同权限SaRouter.match("/events/**").check(r -> {if(StpUtil1.hasPermission("mEvent")==false && StpUtil2.isLogin()==false){throw new SaTokenException("没有权限噢");}});SaRouter.match("/admin/**").check(r -> {if(StpUtil2.isLogin()==false){throw new SaTokenException("没有权限噢");}});SaRouter.match("/advertisement/**").check(r -> {if(StpUtil1.hasPermission("mAdvertisement")==false && StpUtil2.isLogin()==false){throw new SaTokenException("没有权限噢");}});SaRouter.match("/award/**").check(r -> {if(StpUtil1.hasPermission("mAward")==false && StpUtil2.isLogin()==false){throw new SaTokenException("没有权限噢");}});SaRouter.match("/notice/**").check(r -> {if(StpUtil1.hasPermission("mNotice")==false && StpUtil2.isLogin()==false){throw new SaTokenException("没有权限噢");}});})// 异常处理方法:每次setAuth函数出现异常时进入.setError(e -> {System.out.println("---------- sa异常认证");return SaResult.error(e.getMessage());})
// 前置函数:在每次认证函数之前执行.setBeforeAuth(obj -> {// ---------- 设置跨域响应头 ----------SaHolder.getResponse()// 允许指定域访问跨域资源.setHeader("Access-Control-Allow-Origin", "*")// 允许所有请求方式.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")// 有效时间.setHeader("Access-Control-Max-Age", "3600")// 允许的header参数.setHeader("Access-Control-Allow-Headers", "*");// 如果是预检请求,则立即返回到前端SaRouter.match(SaHttpMethod.OPTIONS).free(r -> System.out.println("--------OPTIONS预检请求,不做处理")).back();});}}

那么管理员的权限从哪来呢?不用思考直接看官网。

只要实现了这个接口,就可以设计权限了,ohyeah,真的太腻害了 !

但值得注意的是,因为采用的是Springcloud,所以不能在admin服务那边实现该接口,必须要在网关服务里面实现,否则是没有的!!!!!!!空说无凭,上证据,看官网

实现StpInterface 接口的代码(在网关服务里面实现)

package com.test.auth;import cn.dev33.satoken.stp.StpInterface;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.List;/*** @author LiYa* @create 2023-04-09 16:50* 通过前端传递过来的token可以找到该logintype对应的id*/
@Component
public class stp implements StpInterface {@ResourceRedisTemplate redisTemplate;@Overridepublic List<String> getPermissionList(Object loginId, String loginType) {return (List<String>) redisTemplate.opsForList().range(loginType+loginId, 0,-1);}@Overridepublic List<String> getRoleList(Object loginId, String loginType) {List<String> list =new ArrayList<>();list.add(loginType);return list;}
}

bootstrap.yml

server:port: 8500spring:application:name: gatewaycloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosconfig:extension-configs:- data-id: Gateway-dev.ymlgroup: DEFAULT_GROUPrefresh: true#          - data-id: intercept-dev.yml
#            group: DEFAULT_GROUP
#            refresh: truedata:# redis配置redis:# Redis数据库索引(默认为0)database: 1# Redis服务器地址host: 127.0.0.1# Redis服务器连接端口port: 6379# Redis服务器连接密码(默认为空)# password:# 连接超时时间timeout: 10slettuce:pool:# 连接池最大连接数max-active: 200# 连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: -1ms# 连接池中的最大空闲连接max-idle: 10# 连接池中的最小空闲连接min-idle: 0# Sa-Token配置
sa-token:# token名称 (同时也是cookie名称)token-name: satoken# token有效期,单位秒,-1代表永不过期timeout: 2592000# token临时有效期 (指定时间内无操作就视为token过期),单位秒activity-timeout: -1# 是否允许同一账号并发登录 (为false时新登录挤掉旧登录)is-concurrent: true# 在多人登录同一账号时,是否共用一个token (为false时每次登录新建一个token)is-share: false# token风格token-style: uuid# 是否输出操作日志is-log: false# 是否从cookie中读取tokenis-read-cookie: false

接下来就是测试了,启动服务,访问登录,呐呐呐,看到返回值没有,我们这个时候就可以提取tokenValue和tokenName去访问服务了。

访问redis成功出现数据 。

此时我们去访问某个服务,先不带token访问,毫无疑问被拦截了

设置token,yeah成功有数据返回啦


 总结:看官网,多实践,给博主点赞关注,这样就可以理解解决任何bug,最主要的还是多实践以及给博主点赞关注

SpringCloud3.0+Sa-token+Gateway网关实现鉴权和token登录拦截功能相关推荐

  1. satoken+ gateway网关统一鉴权 初版

    一:感谢大佬 本博客内容 参考了satoken官网实现,satoken官网地址: https://sa-token.cc/doc.html#/micro/gateway-auth 二:项目层级介绍 j ...

  2. SpringCloud整合Sa-Token登录认证+Gateway网关拦截

    Sa-Token介绍:Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证.权限认证.单点登录.OAuth2.0.分布式Session会话.微服务网关鉴权 等一系列权限相关问题 ...

  3. Spring Cloud Gateway实现网关统一鉴权,网关统一Token认证

    需求背景 在微服务的场景下,采用了Spring Cloud Oauth2进行token的管理,实现认证和授权,在这下背景下,有两种解决方案: 网关统一鉴权 此模式适用于网关下的所有模式都是通过一种模式 ...

  4. Gateway网关鉴权

    前言 说起鉴权,大多数会立马想到各种鉴权的技术,比如过滤器.拦截器.安全治理框架shiro.spring-security等等,它们在不同的业务场景下发挥的作用各不相同,但是总体来说都有一个相似的作用 ...

  5. SpringCloud Hoxton版微服务- Gateway网关

    Gateway网关 一.Gateway概念 二.三大核心概念 1.Route (路由) 2.Predicate (断言) 3.Filter (过滤) 三.工作流程图 四.工程搭建 1.新建Gatewa ...

  6. Gateway—网关服务

    ⼀.网关介绍 使用服务网关作为接口服务的统⼀代理,前端通过网关完成服务的统⼀调用 网关可以干什么? 路由:接口服务的统⼀代理,实现前端对接⼝服务的统⼀访问 过滤:对用户请求进行拦截.过滤(用户鉴权). ...

  7. spring cloud gateway网关和链路监控

    文章目录 目录 文章目录 前言 一.网关 1.1 gateway介绍 1.2 如何使用gateway 1.3 网关优化 1.4自定义断言和过滤器 1.4.1 自定义断言 二.Sleuth--链路追踪 ...

  8. SpringCloud系列教程(五)之SpringCloud Gateway 网关聚合开发文档 swagger knife4j 和登录权限统一验证【Hoxton版】

    阅读提醒: 本文面向的是有一定springboot基础者 本次教程使用的Spring Cloud Hoxton RELEASE版本 由于knife4j比swagger更加友好,所以本文集成knife4 ...

  9. Nacos,Sentine限流熔断,Gateway网关

    文章目录 建立项目 注册中心简介 背景分析 Nacos概述 构建Nacos服务 准备工作 If use MySQL as datasource: Count of DB: Connect URL of ...

最新文章

  1. python的翻译-用python实现百度翻译的示例代码
  2. oracle管理mysql_oracle表管理
  3. 210串口控制台-210移植printf不好使
  4. php程序员可能不了解的编程细节
  5. 关于游戏烂代码的那些事(下)
  6. vmware的3种网络模式
  7. rtmp服务器_nginx+windwos 搭建 rtmp 流媒体服务器
  8. 腾讯地图 qq.map 设置鼠标样式
  9. 字符串:2.BF算法(普通模式匹配算法)
  10. C语言流程图生成器的具体操作流程是什么,分享绘制C语言流程图方法
  11. 谷歌搜索没有相机图标_教您如何在Google上搜索图片
  12. 打开ps显示计算机内存不足怎么办,ps内存不足怎么办【解决方法】
  13. 用GDAL打开从USGS下载的img影像文件
  14. 计算机设置ip后提示未识别网络连接,win10设置正确的静态IP,但电脑显示未识别网络,怎么回事。求大佬们帮助啊...
  15. python三国演义人物出场统计txt文本_python实例:三国演义TXT文本词频分析
  16. html点击出现对勾,css伪类右下角点击出现对号角标表示选中的代码
  17. Android View的事件分发机制和滑动冲突解决方案
  18. 基于YOLO目标检测及OpenCV实现的游戏代玩人工智能体(Auto Gaming Agent) [4]
  19. pdf签名无效解决办法_为什么下载下来的电子合同提示有效性未知或至少一个签名有问题?...
  20. bugku--PHP代码审计-sha()函数比较绕过

热门文章

  1. java多态性练习题---主人和狗狗玩接飞盘游戏,狗狗健康值减少10,与主人亲密度增加5 主人和企鹅玩游泳游戏,企鹅健康值减少10,与主人亲密度增加5
  2. 深入理解Callback函数
  3. “5G 是个伪命题?”
  4. Seriousness is an attitude!
  5. CAD2020-objectArx开发笔记---目录
  6. hashlib.md5()函数来筛选出系统重复文件并移除...
  7. 写一个ST语言的跑马灯程序
  8. Freemarker填充数据到word模板中
  9. eclipse java 测试_java-在Eclipse中“未找到JUnit测试”
  10. Junit测试private方法