sa-token进阶

2 篇文章 0 订阅

介绍sa-token实际应用的高阶用法。

路由拦截鉴权

定义配置类SaTokenConfigure->实现WebMvcConfigurer,设置一个只对login请求放通的拦截器:

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SaInterceptor(handle-> StpUtil.checkLogin()))
                .addPathPatterns("/**")
                .excludePathPatterns("/login");
    }
}

测试结果:

我们在未登录的情况下,此时cookie值为空,访问其他接口则返回NotLoginException异常(通常情况下我们可以做个全局异常捕获,如果获取到该异常则用统一格式返回,这里不做详细描述,可以参考:实现全局异常处理):

image-20221219135927945

登录成功之后,cookie值存在,访问其他接口正常:

image-20221219140106216

至此,我们一个简单的登录拦截器就已经实现了。

其实我们可以继续进行优化,使用sa-token封装的SaRouter路由写法使得更容易定义,具体SaRouter的用法可以参考官网-校验函数详解,以下仅为官网示例:

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SaInterceptor(Handler -> {
            // 等同于下方的简写写法
            // SaRouter
            //        // 拦截的path列表 支持写多个
            //        .match("/**")
            //        // 排除掉的path 支持写多个
            //        .notMatch("/login")
            //        // 要执行的校验动作
            //        .check(r -> StpUtil.checkLogin());
            // 可以简写登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
            SaRouter.match("/**", "/login", r -> StpUtil.checkLogin());
            // 角色校验 -- 拦截以 admin 开头的路由,必须具备 admin 角色或者 super-admin 角色才可以通过认证
            SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin"));

            // 根据路由划分模块,不同模块不同鉴权
            SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
        }));
    }
}

绑定角色权限标识

接下来我们介绍如何将自定义的角色和权限标识与sa-token结合在一起。

首先我们需要定义一个StpInterfaceImpl -> 实现StpInterface接口,需要实现两个方法分别是getPermissionList,getRoleList,此处需要注意的是只要配置了角色或者权限标识的拦截,那么每一次请求都会访问这两个方法,可以考虑做个缓存,以避免频繁请求用户信息:

@Component
public class StpInterfaceImpl implements StpInterface {

    /**
     * 返回一个账号所拥有的权限码集合
      * @param loginId  账号id
     * @param loginType 账号类型
     * @return
     */ 
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        // 此处通常对接用户权限表根据loginId查询对应用户的权限信息。此处仅作模拟loginId="1" 则拥有order权限标识,否则没有
        if ("1".equals(loginId)){
            return Arrays.asList("orders");
        }else {
            return Arrays.asList("default");
        }
    }

    /**
     * 返回一个账号所拥有的角色标识集合
      * @param loginId  账号id
     * @param loginType 账号类型
     * @return
     */ 
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        // 此处通常对接用户角色表根据loginId查询对应用户的角色标识信息。此处仅作模拟loginId="666" 表示管理员,否则非管理员
        if ("666".equals(loginId)){
            return Arrays.asList("admin");
        }else {
            return Arrays.asList("general");
        }
    }
}

角色校验/权限校验

结合上一章节中的配置信息,我们创建对应的controller进行测试:

// 角色校验 -- 拦截以 admin 开头的路由,必须具备 admin 角色或者 super-admin 角色才可以通过认证
SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin"));

// 根据路由划分模块,不同模块不同鉴权
SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));

测试角色标识

@RestController
@RequestMapping("/admin")
public class AdminController {

    @GetMapping("/test")
    public String test(){
        return "admin角色允许访问";
    }
}

我们用usId=“2”,即表示没有管理员角色进行访问/admin/test,结果如下表示该用户无此角色被拒:

image-20221219154427345

我们用usId=“666”,即表示管理员角色进行访问/admin/test,结果如下表示用户具备该角色请求放通:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AUzuMozV-1671439109823)(null)]

测试权限标识

@RestController
@RequestMapping("/orders")
public class AdminController {

    @GetMapping("/test")
    public String test(){
        return "orders权限标识允许访问";
    }
}

我们用usId=“2”,即表示没有管理员角色进行访问/orders/test,结果如下表示该用户无此权限被拒:

image-20221219160703980

我们用usId=“1”,即表示管理员角色进行访问/orders/test,结果如下表示用户具备该权限请求放通:

image-20221219160959487

进阶用法

那每一个权限标识或者角色我们都要手动配置到配置类中吗,有没有更加简便的方法在我们写controller就对应好角色和标识的关系。

这里我们需要了解两个注解:

  • @SaCheckRole:角色认证
  • @SaCheckPermission:权限标识

此时我们只需要在管控的controller对应位置上加上注解就能完成配置类中的功能,加在类名上表示该controller下的所有入口遵从认证标识:

@SaCheckRole("admin")
@RestController
@RequestMapping("/admin")
public class AdminController {

    // 所有的请求都需要满足角色admin...
}

@RestController
@RequestMapping("/admin")
public class AdminController {

    // 只有该请求需要满足角色admin
    @SaCheckRole("admin")
    @GetMapping("/testAnno")
    public String testAnno(){
        return "注解方式实现角色放通";
    }
}

同理,权限标识也是如此:

@SaCheckPermission("orders")
@RestController
@RequestMapping("/orders")
public class OrderController {

    // 所有的请求都需要满足权限标识orders...
}
@RestController
@RequestMapping("/orders")
public class OrderController {
    
    @SaCheckPermission("orders")
    @GetMapping("/test")
    public String test(){
        return "orders权限标识允许访问";
    }
}

若存在需要多个权限或者角色标识来判断的情况,我们可以使用如下写法:

// 同时具备大括号中的所有权限标识才放通
@SaCheckPermission({"user-add", "user-delete", "user-update"})
// 只要具备其中一个权限标识就可以进入
@SaCheckPermission(value = {"user-add", "user-delete", "user-update"}, mode = SaMode.OR)

角色注解同理:

// 同时具备大括号中的所有角色才放通
@SaCheckRole({"admin", "my-role"})
// 只要具备其中一个角色就可以进入
@SaCheckRole(value = {"admin", "my-role"}, mode = SaMode.OR)

还有其他相关注解,例如:

  • @SaCheckLogin:登录认证 —— 只有登录之后才能进入该方法
  • @SaCheckSafe:二级认证校验 —— 必须二级认证之后才能进入该方法
  • @SaCheckBasic:HttpBasic认证 —— 只有通过 Basic 认证后才能进入该方法

参考资料:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
sa-token可以通过以下配置来校验token: 1. 配置token名称:在yml配置文件中,可以通过设置`sa-token.token-name`来指定token的名称,例如`sa-token.token-name: X-Token`\[1\]。 2. 配置token有效期:可以通过设置`sa-token.timeout`来指定token的有效期,单位为秒,默认为30天,可以设置为-1代表永不过期,例如`sa-token.timeout: 2592000`\[1\]。 3. 配置token临时有效期:可以通过设置`sa-token.activity-timeout`来指定token的临时有效期,即在指定时间内无操作就视为token过期,单位为秒,默认为-1,表示不设置临时有效期,例如`sa-token.activity-timeout: -1`\[1\]。 4. 配置是否允许同一账号并发登录:可以通过设置`sa-token.is-concurrent`来指定是否允许同一账号并发登录,为true时允许一起登录,为false时新登录会挤掉旧登录,例如`sa-token.is-concurrent: true`\[1\]。 5. 配置是否共用一个token:可以通过设置`sa-token.is-share`来指定在多人登录同一账号时,是否共用一个token,为true时所有登录共用一个token,为false时每次登录会新建一个token,例如`sa-token.is-share: true`\[1\]。 6. 配置是否输出操作日志:可以通过设置`sa-token.is-log`来指定是否输出操作日志,为true时输出操作日志,为false时不输出操作日志,例如`sa-token.is-log: false`\[1\]。 7. 配置是否使用cookie保存token:可以通过设置`sa-token.is-read-cookie`来指定是否使用cookie保存token,为true时使用cookie保存token,为false时不使用cookie保存token,例如`sa-token.is-read-cookie: false`\[1\]。 8. 配置是否使用head保存token:可以通过设置`sa-token.is-read-head`来指定是否使用head保存token,为true时使用head保存token,为false时不使用head保存token,例如`sa-token.is-read-head: true`\[1\]。 通过以上配置,sa-token可以根据配置的规则来校验token的有效性。 #### 引用[.reference_title] - *1* [最简单的权限验证实现——使用Sa-Token进行权限验证](https://blog.csdn.net/lp840312696/article/details/127072424)[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^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [探索 Sa-Token (一) SpringBoot 集成 Sa-Token](https://blog.csdn.net/weixin_38982591/article/details/126764928)[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^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值