Sa-token 入门详细教程
🚀项目采用 Spring Boot + Mybatis-Plus + Mysql 8.0 + Sa-Token 1.34
进行Sa-Token的入门详细教程案例
数据库
🦝tips:数据库直接引用了若依框架的部分基础表
数据表:
TableName | 表描述 |
---|---|
sys_user | 用户信息表 |
sys_role | 角色信息表 |
sys_user_role | 用户角色关联表 |
-- MySQL dump 10.13 Distrib 8.0.26, for Win64 (x86_64)
--
-- Host: localhost Database: model
-- ------------------------------------------------------
-- Server version 8.0.26
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `sys_role`
--
DROP TABLE IF EXISTS `sys_role`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `sys_role` (
`role_id` bigint NOT NULL AUTO_INCREMENT COMMENT '角色ID',
`role_name` varchar(30) NOT NULL COMMENT '角色名称',
`role_key` varchar(100) NOT NULL COMMENT '角色权限字符串',
`role_sort` int NOT NULL COMMENT '显示顺序',
`data_scope` char(1) DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)',
`status` char(1) NOT NULL COMMENT '角色状态(0正常 1停用)',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='角色信息表';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `sys_user`
--
DROP TABLE IF EXISTS `sys_user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`dept_id` bigint DEFAULT NULL COMMENT '部门ID',
`login_name` varchar(30) NOT NULL COMMENT '登录账号',
`user_name` varchar(30) DEFAULT '' COMMENT '用户昵称',
`user_type` varchar(2) DEFAULT '00' COMMENT '用户类型(00系统用户 01注册用户)',
`email` varchar(50) DEFAULT '' COMMENT '用户邮箱',
`phonenumber` varchar(11) DEFAULT '' COMMENT '手机号码',
`sex` char(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
`avatar` varchar(100) DEFAULT '' COMMENT '头像路径',
`password` varchar(50) DEFAULT '' COMMENT '密码',
`salt` varchar(20) DEFAULT '' COMMENT '盐加密',
`status` char(1) DEFAULT '0' COMMENT '帐号状态(0正常 1停用)',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
`login_ip` varchar(128) DEFAULT '' COMMENT '最后登录IP',
`login_date` datetime DEFAULT NULL COMMENT '最后登录时间',
`pwd_update_date` datetime DEFAULT NULL COMMENT '密码最后更新时间',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户信息表';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `sys_user_role`
--
DROP TABLE IF EXISTS `sys_user_role`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `sys_user_role` (
`user_id` bigint NOT NULL COMMENT '用户ID',
`role_id` bigint NOT NULL COMMENT '角色ID',
PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户和角色关联表';
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2023-08-13 14:39:37
一、添加pom依赖
😈
pom.xml
依赖文件如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.14</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xxx</groupId>
<artifactId>sa-token</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sa-token</name>
<description>sa-token</description>
<repositories>
<!-网易maven源->
<repository>
<id>nexus-163</id>
<name>Nexus 163</name>
<url>http://mirrors.163.com/maven/repository/maven-public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mysql.version>8.0.26</mysql.version>
<lombok.version>1.18.20</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Springboot-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springBoot Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Sa-Token 权限认证 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.34.0</version>
</dependency>
<!-如果集成redis 将此注释打开 🔽->
<!-- <!– Sa-Token 整合 Redis (使用jackson序列化方式) –>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis-jackson</artifactId>
<version>1.34.0</version>
</dependency>
<!– 提供Redis连接池 –>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<!-- mysql数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!-- 工具类库 -->
<dependency>
<groupId>com.fengwenyi</groupId>
<artifactId>JavaLib</artifactId>
<version>2.1.5</version>
</dependency>
<!--RESTful-->
<dependency>
<groupId>com.fengwenyi</groupId>
<artifactId>api-result</artifactId>
<version>2.5.1</version>
</dependency>
<!-- SpringBoot参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- druid 德鲁伊连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<!-- 代码自动生成器依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>1.9.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
二、配置
application.yml
文件
application.yml
server:
port: 8080
# Sa-Token
sa-token:
token-name: sa-token # token-NAME cookie名称
timeout: 60 # token有效时间 (默认30天) 单位 S 秒
activity-timeout: -1 # token 临时有效时间 单位 S 秒
is-concurrent: false
is-share: false # token 是否共用
token-style: uuid
is-log: true # 是否输出操作日志
spring:
application:
name: sa-token
# 数据库配置
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/model?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
type: com.alibaba.druid.pool.DruidDataSource
# redis配置 [⭕如果不使用reids可以不配置]
redis:
database: 1 # 数据库索引(默认为0)
host: 127.0.0.1 # ip
port: 6379
timeout: 60s # 连接超时时间seconds
lettuce:
pool:
max-active: 200 # 最大连接池数
max-wait: -1ms # 最大阻塞等待时间 (负值没有限制)
max-idle: 10 # 最大空闲连接数
min-idle: 0 # 最小空闲连接数
# mybatis-plus
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
call-setters-on-nulls: true
global-config:
db-config:
logic-delete-value: true
logic-not-delete-value: false
id-type: auto
db-type: mysql
三、项目相关配置
1、通过mybatis-plus 自动生成代码
代码自动生成相关配置
创建
CodeGenerator.java
package com.xxx.satoken.generator;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.platform.commons.util.StringUtils;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @description: TODO
* @author: xxx
* @date 2023/8/12 21:46
*/
public class CodeGenerator {
public static String scanner(String tableName) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("输入" + tableName + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String table = scanner.next();
if (StringUtils.isNotBlank(table)) {
return table;
}
}
throw new MybatisPlusException("请输入正确的" + tableName + "!");
}
public static void main(String[] args) {
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");//设置代码生成路径
gc.setFileOverride(true);//是否覆盖以前文件
gc.setOpen(false);//是否打开生成目录
gc.setAuthor("xxx");//设置项目作者名称
gc.setIdType(IdType.AUTO);//设置主键策略
gc.setBaseResultMap(true);//生成基本ResultMap
gc.setBaseColumnList(true);//生成基本ColumnList
gc.setServiceName("%sService");//去掉服务默认前缀
gc.setDateType(DateType.ONLY_DATE);//设置时间类型
mpg.setGlobalConfig(gc);
// 数据库相关信息配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/model?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
// 相关包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.xxx.satoken");// " xxx "按实际情况更改
pc.setMapper("mapper");
pc.setXml("mapper.xml");
pc.setEntity("model");
pc.setService("service");
pc.setServiceImpl("service.impl");
pc.setController("controller");
mpg.setPackageInfo(pc);
// 策略配置
StrategyConfig sc = new StrategyConfig();
sc.setNaming(NamingStrategy.underline_to_camel);
sc.setColumnNaming(NamingStrategy.underline_to_camel);
sc.setEntityLombokModel(true);//自动lombok
sc.setRestControllerStyle(true);
sc.setControllerMappingHyphenStyle(true);
sc.setLogicDeleteFieldName("deleted");//设置逻辑删除
//设置自动填充配置
TableFill gmt_create = new TableFill("create_time", FieldFill.INSERT);
TableFill gmt_modified = new TableFill("update_time", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills=new ArrayList<>();
tableFills.add(gmt_create);
tableFills.add(gmt_modified);
sc.setTableFillList(tableFills);
//乐观锁
sc.setVersionFieldName("version");
sc.setRestControllerStyle(true);//驼峰命名
// sc.setTablePrefix("tbl_"); 设置表名前缀
sc.setInclude(scanner("表名,英文逗号分割").split(","));
mpg.setStrategy(sc);
// 生成代码
mpg.execute();
}
}
如果配置了
create_time
、
update_time
需要配置自动插入相关参数
package com.xxx.satoken.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* @description: TODO
* @author: xxx
* @date 2023/8/12 21:56
*/
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill...");
this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill...");
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
2.自动生成代码后的目录结构如下
3.配置一下相关的service、mapper、controller就可以了
– mapper
package com.xxx.satoken.mapper;
import com.wangtao.satoken.model.SysUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.Map;
/**
* <p>
* 用户信息表 Mapper 接口
* </p>
*
* @author xxx
* @since 2023-08-12
*/
@Repository
public interface SysUserMapper extends BaseMapper<SysUser> {
}
– service
package com.xxx.satoken.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wangtao.satoken.model.SysUser;
import com.wangtao.satoken.mapper.SysUserMapper;
import com.wangtao.satoken.service.SysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* 用户信息表 服务实现类
* </p>
*
* @author xxx
* @since 2023-08-12
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
@Autowired
private SysUserMapper userDao;
@Override
public SysUser queryUser(String username) {
QueryWrapper<SysUser> userWrapper = new QueryWrapper();
userWrapper.eq("login_name",username);// mybatis-plus 自定义通过login_name查询用户
return userDao.selectOne(userWrapper);
}
}
– controller
package com.xxx.satoken.controller;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.fengwenyi.api.result.IReturnCode;
import com.wangtao.satoken.model.SysUser;
import com.wangtao.satoken.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.fengwenyi.api.result.ResponseTemplate;
import java.util.List;
/**
* <p>
* 用户信息表 前端控制器
* </p>
*
* @author xxx
* @since 2023-08-12
*/
@RestController
@RequestMapping("/user")
public class SysUserController {
@Autowired
private SysUserService userService;
/**
*
* @param username
* @param password
* @return ResponseTemplate<T> 这个是 api-result 工具的api可以直接返回RESTful风格的结果
*/
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ResponseTemplate<SysUser> login(@RequestParam("username") String username,
@RequestParam("password") String password){
SysUser currentUser = userService.queryUser(username);
if (null != currentUser){
if ( password.equals(currentUser.getPassword()) ) {
StpUtil.login(currentUser.getUserId());
// 这里直接返回的用户信息,方便测试
return ResponseTemplate.success(currentUser);
}
return ResponseTemplate.fail(IReturnCode.Default.USER_PASSWORD_INCORRECT);
}
return ResponseTemplate.fail(IReturnCode.Default.USER_NOT_EXIST);
}
// 查询登录状态
@RequestMapping("isLogin")
public String isLogin() {
return "当前会话是否登录:" + StpUtil.isLogin();
}
/**
* 登录注销
* @return SaResult 这个是Sa-Token自己的返回类型
*/
@RequestMapping(value = "logout")
public SaResult logout() {
StpUtil.logout();
return SaResult.ok();
}
}
四、启动项目
项目启动成功
五、测试
我是用的
Apifox
进行测试
login测试
在线认证 isLogin
版权声明:本文为SD_Tunsll原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。