SpringBoot 整合 Sa-Token 让鉴权更简单

原创 默存 全栈客 2023-10-24 10:23 发表于甘肃

收录于合集

#SpringBoot6个

#Java8个

#环境搭建2个

Sa-Token 简介

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

官方文档:https://sa-token.cc/doc.html

功能一览

图片

项目示例

https://gitee.com/typ1805/springboot-master/tree/master/springboot-satoken

SpringBoot 集成

创建数据库表

CREATE TABLE `user`  (
 `id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键ID',
 `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '账号',
 `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '密码',
 `create_time` datetime(0) DEFAULT NULL COMMENT '创建时间',
 PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- 测试数据
INSERT INTO `user` VALUES ('u00001', 'admin', '123456', '2023-03-15 16:27:34');

pom.xml 依赖

<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.34.0</version>
</dependency>

application.yml 配置

# Sa-Token 配置
sa-token:
  # token名称 (同时也是cookie名称)
  token-name: token
  # token有效期,单位s 默认30天, -1代表永不过期
  timeout: 2592000
  # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
  activity-timeout: -1
  # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
  is-concurrent: true
  # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
  is-share: true
  # token风格
  token-style: uuid
  # 是否输出操作日志
  is-log: false

鉴权拦截器配置

package com.example.satoken.config;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @ClassName:SaTokenConfigure.java
 * @ClassPath:com.example.satoken.config.SaTokenConfigure.java
 * @Description: 鉴权拦截器
 * @Author:tanyp
 * @Date:2023/10/24  09:14
 **/
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {

    /**
     * @MonthName:addInterceptors
     * @Description: 注册 Sa-Token 拦截器,打开注解式鉴权功能
     * @Author:tanyp
     * @Date: 023/10/24  09:19
     * @Param: [registry]
     * @return:void
     **/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token 拦截器,打开注解式鉴权功能
        registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
                // 验证所有接口
                .addPathPatterns("/**")
                // 忽略校验
                .excludePathPatterns("/user/login");
    }
}

路由拦截鉴权配置

// 根据路由划分模块,不同模块不同鉴权 
registry.addInterceptor(new SaInterceptor(handler -> {
    SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
    SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
    // 更多模块... 
})).addPathPatterns("/**");

全局异常拦截配置

package com.example.satoken.exception;

import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @ClassName:GlobalExceptionHandler.java
 * @ClassPath:com.example.satoken.exception.GlobalExceptionHandler.java
 * @Description: 全局异常拦截
 * @Author:tanyp
 * @Date:2023/10/24 10:25
 **/
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler
    public SaResult handlerException(Exception e) {
        e.printStackTrace();
        return SaResult.error(e.getMessage());
    }

}

用户信息(UserController.java)

package com.example.satoken.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.satoken.domain.User;
import com.example.satoken.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * @ClassName:UserController.java
 * @ClassPath:com.example.satoken.controller.UserController.java
 * @Description: 用户信息
 * @Author:tanyp
 * @Date:2023/10/24 10:28
 **/
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("login")
    public Object login(String username, String password) {
        User user = userService.getOne(Wrappers.<User>lambdaQuery().ge(User::getUsername, username));
        if (Objects.nonNull(user) && Objects.equals(user.getUsername(), username) && Objects.equals(user.getPassword(), password)) {
            // 登录鉴权
            StpUtil.login(user.getId());
            // 返回token信息
            return StpUtil.getTokenInfo();
        }
        return "登录失败,用户名或密码有误!";
    }

    @GetMapping("logout")
    public Object logout() {
        StpUtil.logout();
        return "登出成功!";
    }

}
  • • StpUtil.login():会话登录,参数填登录人的账号id;

  • • StpUtil.checkLogin():校验当前客户端是否已经登录;

  • • StpUtil.getTokenInfo():获取当前会话的 token 信息参数;

  • • StpUtil.getTokenValue():获取当前会话的 token 值;

  • • StpUtil.getTokenTimeout():获取当前会话剩余有效期(单位:s,返回-1代表永久有效);

  • • StpUtil.getLoginId():获取当前会话账号id;

  • • StpUtil.kickout():将指定账号踢下线;

  • • StpUtil.logout():强制指定账号注销下线;

注解鉴权(TestController.java)

package com.example.satoken.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName:TestController.java
 * @ClassPath:com.example.satoken.controller.TestController.java
 * @Description: 注解鉴权
 * @Author:tanyp
 * @Date:2023/10/24 10:30
 **/
@SaCheckLogin // 登录校验 —— 只有登录之后才能进入该方法。
@RestController
@RequestMapping("/test")
public class TestController {

    /**
     * @MonthName:test
     * @Description: 忽略校验 —— 表示被修饰的方法或类无需进行注解鉴权和路由拦截器鉴权。
     * @Author:tanyp
     * @Date:2023/10/24 10:30
     * @Param: []
     * @return:java.lang.String
     **/
    @SaIgnore // 忽略校验
    @GetMapping("test")
    public String test() {
        return "当前会话是否登录:" + StpUtil.isLogin();
    }

}
  • • @SaCheckLogin:登录校验,只有登录之后才能进入该方法;

  • • @SaIgnore:忽略校验;

  • • @SaCheckDisable("comment"):账号服务封禁校验,校验当前账号指定服务是否被封禁。

Session 会话

Session 是会话中专业的数据缓存组件,通过 Session 我们可以很方便的缓存一些高频读写数据,提高程序性能。

设置登录信息缓存 user 对象 :

StpUtil.getSession().set("user", user);

在任意处使用这个 user 对象

SysUser user = (SysUser) StpUtil.getSession().get("user");

登录测试

请求地址:

http://localhost:8080/user/login?username=admin&password=123456

结果:

"tokenName": "token",
"tokenValue": "f2e6563b-9aed-44ef-8e3e-6d2e48ca6cef",
"isLogin": true,
"loginId": "u00001",
"loginType": "login",
"tokenTimeout": 2591999,
"sessionTimeout": 2591999,
"tokenSessionTimeout": -2,
"tokenActivityTimeout": -1,
"loginDevice": "default-device",
"tag": null

更多API文档:

https://sa-token.cc/doc.html#/use/login-auth

欢迎关注

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot整合sa-token,可以按照以下步骤进行操作。 1. 添加依赖:在`pom.xml`文件中添加sa-token的Redis集成包依赖。可以使用官方提供的Redis集成包`sa-token-dao-redis-jackson`,具体依赖如下: ``` <dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-dao-redis-jackson</artifactId> <version>1.34.0</version> </dependency> ``` 2. 配置sa-token:在SpringBoot的配置文件中,配置sa-token的相关属性,包括Redis连接信息、token有效期等。可以参考sa-token的官方文档进行配置。 3. 注解鉴权:在需要进行鉴权的方法上添加相应的注解。例如,使用`@SaCheckLogin`注解表示该方法需要登录认证,使用`@SaCheckRole`注解表示该方法需要具有指定角色才能访问。可以根据具体需求选择合适的注解进行鉴权。 4. 注册拦截器:在高版本的SpringBoot中(≥2.6.x),需要额外添加`@EnableWebMvc`注解才能使注册拦截器生效。可以在配置类上添加该注解。 通过以上步骤,就可以在SpringBoot中成功整合sa-token,并实现基于注解的鉴权功能。请根据具体需求进行配置和使用。 #### 引用[.reference_title] - *1* [【SaToken使用】SpringBoot整合SaToken(一)token自动续期+token定期刷新+注解鉴权](https://blog.csdn.net/weixin_43165220/article/details/126889045)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [springboot整合sa-token](https://blog.csdn.net/weixin_43296313/article/details/124274443)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Spring Boot中使用Sa-Token实现轻量级登录与鉴权](https://blog.csdn.net/m0_71777195/article/details/129175616)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值