Spring Boot(四) 快速开发 Sa-token

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情

大家好! 我是慕歌,一只想教你学习 Spring Boot的野生coder! 欢迎来到慕歌的 Sping boot系列教程,希望通过这个教程带大家搭建基础的 Spring Boot项目,该教程所有知识点均来源于本人的真实开发!

前言

前一节我们介绍了如何通过sa-token 实现最基础的登录认证,在开发过程中我们会对sa-token 的一系列功能进行使用,慕歌将就自己的项目向大家展示sa-token 的一些功能,如登录校验、登录检测、封禁用户,token 校验,多租户模式等功能... 如果后续还有对sa-token 的进一步学习,我也会第一时间向大家分享!
如果大家想深入理解sa-token 权限框架,可仔细阅读官方文档,以及源码。
官网:sa-token.dev33.cn/doc/index.h…
源码:gitee.com/dromara/sa-…

导包:

在后续的开发中,我们将会把用户的登录状态信息,存储在redis 中,保证用户的登录更加稳定,快速

        <!-- Sa-Token 整合 Redis (使用 jdk 默认序列化方式) -->
        <dependency>
            <groupId>cn.dev33</groupId>
            <artifactId>sa-token-dao-redis</artifactId>
            <version>1.30.0</version>
        </dependency>

        <!-- redis 缓存操作 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--连接池依赖-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
复制代码

权限校验:

在进行登录验证的同时,进行权限校验也是重要的一环,sa-token通过拦截器,为我们的权限校验进行了拓展,让我们可以在全局工程中随处进行权限控制。并且依赖于上一节介绍的注解式开发,使得整个校验过程更加的简洁,明了。

/**
 * 注入权限组
 */
@Component
public class StpInterfaceImpl implements StpInterface {
    //权限
    @Autowired
    AdminPowerMapper adminPowerMapper;
    //角色
    @Autowired
    AdminRolesMapper adminRolesMapperl;

    /**
     * 用户权限
     * @param loginId 登录id
     * @param s
     * @return
     */
    @Override
    public List<String> getPermissionList(Object loginId, String s) {
        //获得登录的用户id 对应权限
        List<String> userPermissions = adminPowerMapper.getUserPermissions(loginId);
        System.out.println("permiassion - list : "+userPermissions);
        return userPermissions;
    }

    /**
     * 用户角色
     * @param loginId 登录id
     * @param s
     * @return
     */
    @Override
    public List<String> getRoleList(Object loginId, String s) {
        //获得登录的用户id 对应角色
        List<String> userRoles = adminRolesMapperl.getUserRole(loginId);
        System.out.println("role - list : "+userRoles);
        return userRoles;
    }
}
复制代码
在我的开发中,引入了两层控制,角色表,权限表,进行细颗粒的权限控制,更好保证数据见的隔离。附上我的角色表于权限表的设计源码:
复制代码
create table cf_admin_power
(
    id          int unsigned auto_increment comment '权限id'
        primary key,
    code        varchar(32)                not null comment '权限码',
    name        char(32)                   not null comment '权限名',
    level       char(32)                   not null comment '等级',
    icon        varchar(255)               null comment '图标',
    is_show     tinyint unsigned default 1 not null comment '是否显示(0:否,1:是)',
    status      tinyint unsigned default 1 not null comment '状态(1:可用,2:停用,3:已删除)',
    create_time datetime                   not null comment '创建时间',
    update_time datetime                   not null comment '更新时间'
)
    comment '权限表
' collate = utf8_unicode_ci;
复制代码
-- auto-generated definition
create table cf_admin_roles
(
    id          int unsigned auto_increment comment '角色id'
        primary key,
    name        char(32)                   not null comment '角色名称',
    role_info   char(32)                   null comment '角色描述',
    is_super    tinyint unsigned default 0 not null comment '是超级管理员(1:是,0:否)',
    status      tinyint unsigned default 1 not null comment '状态(1:可用,2:停用,3:已删除)',
    create_time datetime                   null comment '创建时间',
    update_time datetime                   null comment '更新时间'
)
    comment '角色组表' collate = utf8_unicode_ci;
复制代码

在为用户注入权限后,权限的校验就变得简单起来了,只需要简单的注解,调用即可校验权限。就在这样的一个校验注解,就可以实现用户角色,用户权限的检查

// 角色认证:必须具有指定角色才能进入该方法 
@SaCheckRole("super-admin")     
// 权限认证:必须具有指定权限才能进入该方法 
@SaCheckPermission("user-add") 
//三个权限并列,满足一个则通过
@SaCheckPermission(value = {"user-add", "user-all", "user-delete"}, mode = SaMode.OR)
//同时满足角色和权限,通过
@SaCheckPermission(value = "user-add", orRole = "admin") 
复制代码

token:

框架为我们提供了多种token生成方式,以及token 的校验规则,将一个用户标记为登录状态后,该用户就进入sa-token 中进行统一管理。在配置redis 后,即可实现到重启数据不丢失,而且保证分布式环境下多节点的会话一致性。

//登录
StpUtil.login(user.getId());
// 踢下线
StpUtil.kickout(adminUser.getId());
//冻结
StpUtil.disable(adminUser.getId(), -1);
// 获取 Token  相关参数
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
复制代码

在前后台的开发中,我们可以将登录信息回传,即可实现前端通过token 建立访问,前后端分离。前端可将登录后返回的token 保存,之后每次进行数据访问时携带token ,后端便可以对请求者的权限信息校验。

//回传数据
"data":{11 items
	"tokenName":"satoken"
	"tokenValue":"6046ddd3-71cd-4509-b9ca-b842790bda72"
	"isLogin":true
	"loginId":"1002"
	"loginType":"login"
	"tokenTimeout":2592000
	"sessionTimeout":2591999
	"tokenSessionTimeout":-2
	"tokenActivityTimeout":-1
	"loginDevice":"default-device"
	"tag":NULL
}
//redis 缓存数据
satoken:login:token:6046ddd3-71cd-4509-b9ca-b842790bda72
复制代码

多租户模式:

在我的开发中,分官网用户和后台用户,他们是完全不同的两组数据,具有各自独立的权限,这时候需要使用到多租户模式,对不同的用户组维护各自的权限。sa-token为我们实现了一种简单的方式,对不同的组加上对应的标签。之后实现sa-token 的校验模式,便可同标准使用方式一样,对自己的用户组校验。

public class StpAdminUtil {
        //权限组 类型 admin
        public static final String TYPE = "admin";
        //底层logic 静态类
        public static StpLogic stpLogic = new StpLogic("admin");

        public StpAdminUtil() {
        }

        public static String getLoginType() {
            return stpLogic.getLoginType();
        }

        public static void setStpLogic(StpLogic stpLogic) {
            cn.dev33.satoken.stp.StpUtil.stpLogic = stpLogic;
            SaManager.putStpLogic(stpLogic);
        }
}

/**
 * 聚合接口
 */
@Configuration
public class SaMultiConfig {
    @Autowired
    public void rewriteSaStrategy() {
        // 重写Sa-Token的注解处理器,增加注解合并功能
        SaStrategy.me.getAnnotation = (element, annotationClass) -> {
            return AnnotatedElementUtils.getMergedAnnotation(element, annotationClass);
        };
    }
}

/**
 * 登录认证(User版):只有登录之后才能进入该方法
 * <p> 可标注在函数、类上(效果等同于标注在此类的所有方法上)
 */
@SaCheckLogin(type = "admin")
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE})
public @interface SaAdminCheckLogin {
}
复制代码

结语

这一章的分享到这里就结束了,下一节中还将带来另一个好用的工具类 Hutool的分享!
如果您觉得本文不错,欢迎点赞支持,您的关注是我坚持的动力!

猜你喜欢

转载自juejin.im/post/7128312090879590436