Sa-Token的用户统一鉴权开发

引入依赖

<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot3-starter</artifactId>
    <version>1.37.0</version>
</dependency>

配置信息

sa-token: 
    # token 名称(同时也是 cookie 名称)
    token-name: satoken
    # token 有效期(单位:秒) 默认30天,-1 代表永久有效
    timeout: 2592000
    # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
    active-timeout: -1
    # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
    is-concurrent: true
    # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
    is-share: true
    # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
    token-style: uuid
    # 是否输出操作日志 
    is-log: true

代码解析

定义权限类型和用户类型

public enum UserPermission {
    //基本权限
    BASIC,
    //实名认证权限
    AUTH,
    //无任何权限
    NONE;
}
public enum UserRole {
    //普通用户
    CUSTOMER,
    //管理员
    ADMIN;
}

登录时将用户信息写入session

//查询用户信息的代码
....
//登录
StpUtil.login(userInfo.getUserId(), new SaLoginModel().setIsLastingCookie(loginParam.getRememberMe())
        .setTimeout(DEFAULT_LOGIN_SESSION_TIMEOUT));
//通过StpUtil将用户id存入session
StpUtil.getSession().set(userInfo.getUserId().toString(), userInfo);

通过StpUtil读取session获取用户信息,自定义实现自带StpInterface接口的getPermissionListgetRoleList方法,来获取用户的权限List和角色List。

@Component
public class StpInterfaceImpl implements StpInterface {
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        // 通过StpUtil读取session获取用户id
        UserInfo userInfo = (UserInfo) StpUtil.getSessionByLoginId(loginId).get((String) loginId);

        if (userInfo.getUserRole() == UserRole.ADMIN || userInfo.getState().equals(UserStateEnum.ACTIVE.name()) || userInfo.getState().equals(UserStateEnum.AUTH.name()) ) {
            return List.of(UserPermission.BASIC.name(), UserPermission.AUTH.name());
        }

        if (userInfo.getState().equals(UserStateEnum.INIT.name())) {
            return List.of(UserPermission.BASIC.name());
        }

        if (userInfo.getState().equals(UserStateEnum.FROZEN.name())) {
            return List.of(UserPermission.FROZEN.name());
        }

        return List.of(UserPermission.NONE.name());
    }

    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        UserInfo userInfo = (UserInfo) StpUtil.getSessionByLoginId(loginId).get((String) loginId);
        if (userInfo.getUserRole() == UserRole.ADMIN) {
            return List.of(UserRole.ADMIN.name());
        }
        return List.of(UserRole.CUSTOMER.name());
    }
}

通过SaToken鉴权

public SaReactorFilter getSaReactorFilter() {
        return new SaReactorFilter()
                // 拦截地址
                .addInclude("/**")
                // 开放地址
                .addExclude("/favicon.ico")
                // 鉴权方法:每次访问进入
                .setAuth(obj -> {
                    // 登录校验 -- 拦截所有路由,并排除/login 用于开放登录
                    SaRouter.match("/**").notMatch("/login/**").check(r -> StpUtil.checkLogin());
                    // 权限认证 -- 不同模块, 校验不同权限
                    SaRouter.match("/admin/**", r -> StpUtil.checkRole(UserRole.ADMIN.name()));
                    SaRouter.match("/pay/**", r -> StpUtil.checkPermission(UserPermission.AUTH.name()));
                    SaRouter.match("/user/**", r -> StpUtil.checkPermissionOr(UserPermission.BASIC.name(), UserPermission.AUTH.name()));
                    SaRouter.match("/order/**", r -> StpUtil.checkPermissionOr(UserPermission.BASIC.name(),UserPermission.AUTH.name()));
                })
                // 异常处理方法:每次setAuth函数出现异常时进入
                .setError(this::getSaResult);
}

权限异常处理

private SaResult getSaResult(Throwable throwable) {
        switch (throwable) {
            case NotLoginException notLoginException:
                log.error("请先登录");
                return SaResult.error("请先登录");
            case NotRoleException notRoleException:
                if (UserRole.ADMIN.name().equals(notRoleException.getRole())) {
                    log.error("请勿越权使用!");
                    return SaResult.error("请勿越权使用!");
                }
                log.error("您无权限进行此操作!");
                return SaResult.error("您无权限进行此操作!");
            case NotPermissionException notPermissionException:
                if (UserPermission.AUTH.name().equals(notPermissionException.getPermission())) {
                    log.error("请先完成实名认证!");
                    return SaResult.error("请先完成实名认证!");
                }
                log.error("您无权限进行此操作!");
                return SaResult.error("您无权限进行此操作!");
            default:
                return SaResult.error(throwable.getMessage());
        }
}

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部