SaToken - 2. 踢人下线 - 注解鉴权

1. Sa-Token 踢人下线


  • Sa-Token官方文档链接: Sa-Token 踢人下线
  • 踢人下线核心操作就是找到指定 **loginId** 对应的 **Token**,并设置其失效。

img

强制注销 和 踢人下线 的区别在于:

  • 强制注销等价于对方主动调用了注销方法,再次访问会提示:Token无效。
  • 踢人下线不会清除Token信息,而是将其打上特定标记,再次访问会提示:Token已被踢下线。

1. 强制注销

StpUtil.logout(10001);                    // 强制指定账号注销下线 
StpUtil.logout(10001, "PC");              // 强制指定账号指定端注销下线 
StpUtil.logoutByTokenValue("token");      // 强制指定 Token 注销下线 

2. 踢人下线

StpUtil.kickout(10001);                    // 将指定账号踢下线 
StpUtil.kickout(10001, "PC");              // 将指定账号指定端踢下线
StpUtil.kickoutByTokenValue("token");      // 将指定 Token 踢下线

3. 测试小demo

package com.ccovo.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.ccovo.domain.R;
import com.ccovo.domain.constants.Constants;
import com.ccovo.enums.ErrorCode;
import com.ccovo.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Api(tags = "踢人下线接口")
@RequestMapping("/kictout")
public class KickoutController {

    /**
     * 强制注销等价于对方主动调用了注销方法,再次访问会提示:Token无效。
     * 踢人下线不会清除Token信息,而是将其打上特定标记,再次访问会提示:Token已被踢下线。
     */


    /**
     * 强制指定账号注销下线
     */
    @ApiOperation(value = "强制指定账号注销下线")
    @PostMapping("/logout")
    public R<?> logout(Long loginId) {
        StpUtil.logout(loginId);
        return R.ok();
    }

    /**
     * 强制指定账号指定端注销下线
     */
    @ApiOperation(value = "强制指定账号指定端注销下线")
    @PostMapping("/logoutByLoginKey")
    public R<?> logoutByLoginKey(Long loginId, String device) {
        StpUtil.logout(loginId, device);
        return R.ok();
    }

    /**
     * 指定Token注销下线
     */
    @ApiOperation(value = "指定Token注销下线")
    @PostMapping("/logoutByTokenValue")
    public R<?> logoutByTokenValue(String tokenValue) {
        StpUtil.logoutByTokenValue(tokenValue);
        return R.ok();
    }

    /**
     * 指定账号踢下线
     */
    @ApiOperation(value = "指定账号踢下线")
    @PostMapping("/kickout")
    public R<?> kickout(Long loginId) {
        StpUtil.kickout(loginId);
        return R.ok();
    }

    /**
     * 指定账号指定端踢下线
     */
    @ApiOperation(value = "指定账号指定端踢下线")
    @PostMapping("/kickoutByLoginKey")
    public R<?> kickoutByLoginKey(Long loginId, String device) {
        StpUtil.kickout(loginId, device);
        return R.ok();
    }

    /**
     * 指定Token踢下线
     */
    @ApiOperation(value = "指定Token踢下线")
    @PostMapping("/kickoutByTokenValue")
    public R<?> kickoutByTokenValue(String tokenValue) {
        StpUtil.kickoutByTokenValue(tokenValue);
        return R.ok();
    }



}

2. Sa-Token 注解鉴权


注解鉴权 —— 优雅的将鉴权与业务代码分离!

  • @SaCheckLogin: 登录校验 —— 只有登录之后才能进入该方法。
  • @SaCheckRole("admin"): 角色校验 —— 必须具有指定角色标识才能进入该方法。
  • @SaCheckPermission("user:add"): 权限校验 —— 必须具有指定权限才能进入该方法。
  • @SaCheckSafe: 二级认证校验 —— 必须二级认证之后才能进入该方法。
  • @SaCheckHttpBasic: HttpBasic校验 —— 只有通过 HttpBasic 认证后才能进入该方法。
  • @SaCheckHttpDigest: HttpDigest校验 —— 只有通过 HttpDigest 认证后才能进入该方法。
  • @SaIgnore:忽略校验 —— 表示被修饰的方法或类无需进行注解鉴权和路由拦截器鉴权。
  • @SaCheckDisable("comment"):账号服务封禁校验 —— 校验当前账号指定服务是否被封禁。

1. 注册拦截器

package com.ccovo.config.satoken;

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

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    // 注册 Sa-Token 拦截器,打开注解式鉴权功能
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token 拦截器,打开注解式鉴权功能
        registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
    }

    // 拦截除了 /user/doLogin 的所有请求,并且需要用户已登录才可放行
//    @Override
//    public void addInterceptors(InterceptorRegistry registry) {
//        // 注册 Sa-Token 拦截器,校验规则为 StpUtil.checkLogin() 登录校验。
//        registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
//                .addPathPatterns("/**")
//                // 放行接口文档相关路径
//                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**",
//                        "/api", "/api-docs", "/api-docs/**", "/doc.html*", "/doc.html#/**")
//                .excludePathPatterns("/login");
//    }

}

2. 使用注解鉴权

  • 以下注解都可以加在类上,代表为这个类所有方法进行鉴权
// 登录校验:只有登录之后才能进入该方法 
@SaCheckLogin                        
@RequestMapping("info")
public String info() {
    return "查询用户信息";
}

// 角色校验:必须具有指定角色才能进入该方法 
@SaCheckRole("super-admin")        
@RequestMapping("add")
public String add() {
    return "用户增加";
}

// 权限校验:必须具有指定权限才能进入该方法 
@SaCheckPermission("user-add")        
@RequestMapping("add")
public String add() {
    return "用户增加";
}

// 二级认证校验:必须二级认证之后才能进入该方法 
@SaCheckSafe()        
@RequestMapping("add")
public String add() {
    return "用户增加";
}

// Http Basic 校验:只有通过 Http Basic 认证后才能进入该方法 
@SaCheckHttpBasic(account = "sa:123456")
@RequestMapping("add")
public String add() {
    return "用户增加";
}

// Http Digest 校验:只有通过 Http Digest 认证后才能进入该方法 
@SaCheckHttpDigest(value = "sa:123456")
@RequestMapping("add")
public String add() {
    return "用户增加";
}

// 校验当前账号是否被封禁 comment 服务,如果已被封禁会抛出异常,无法进入方法 
@SaCheckDisable("comment")                
@RequestMapping("send")
public String send() {
    return "查询用户信息";
}

3. 设定校验模式

  • @SaCheckRole@SaCheckPermission注解可设置校验模式,例如:
  • SaMode.AND,标注一组权限,会话必须全部具有才可通过校验。
  • SaMode.OR,标注一组权限,会话只要具有其一即可通过校验。
// 注解式鉴权:只要具有其中一个权限即可通过校验 
@RequestMapping("atJurOr")
@SaCheckPermission(value = {"user-add", "user-all", "user-delete"}, mode = SaMode.OR)        
public SaResult atJurOr() {
    return SaResult.data("用户信息");
}

// 注解式鉴权:满足所有权限即可通过校验 
@RequestMapping("atJurAnd")
@SaCheckPermission(value = {"user-add", "user-all", "user-delete"}, mode = SaMode.AND)        
public SaResult atJurAnd() {
    return SaResult.data("用户信息");
}

4. 角色权限双重OR校验

orRole 代表权限校验未通过时的次要选择,两者只要其一校验成功即可进入请求方法,其有三种写法:

  • 写法一:orRole = "admin",代表需要拥有角色 admin 。
  • 写法二:orRole = {"admin", "manager", "staff"},代表具有三个角色其一即可。
  • 写法三:orRole = {"admin, manager, staff"},代表必须同时具有三个角色。
// 角色权限双重 “or校验”:具备指定权限或者指定角色即可通过校验
@RequestMapping("userAdd")
@SaCheckPermission(value = "user.add", orRole = "admin")        
public SaResult userAdd() {
    return SaResult.data("用户信息");
}

5. 忽略认证

  • @SaIgnore 修饰方法时代表方法可以被游客访问,修饰类时代表类中的所有接口都可以游客访问。
  • @SaIgnore 有最高优先级,当 @SaIgnore 和其它鉴权注解一起出现时,其它鉴权注解都将被忽略。
  • @SaIgnore 可以忽略掉 Sa-Token 拦截器中的路由鉴权。
@SaCheckLogin
@RestController
public class TestController {
    
    // ... 其它方法 
    
    // 此接口加上了 @SaIgnore 可以游客访问 
    @SaIgnore
    @RequestMapping("getList")
    public SaResult getList() {
        // ... 
        return SaResult.ok(); 
    }
}

6. 批量注解鉴权

// 在 `@SaCheckOr` 中可以指定多个注解,只要当前会话满足其中一个注解即可通过验证,进入方法。
@SaCheckOr(
        login = @SaCheckLogin,
        role = @SaCheckRole("admin"),
        permission = @SaCheckPermission("user.add"),
        safe = @SaCheckSafe("update-password"),
        httpBasic = @SaCheckHttpBasic(account = "sa:123456"),
        disable = @SaCheckDisable("submit-orders")
)
@RequestMapping("test")
public SaResult test() {
    // ... 
    return SaResult.ok(); 
}

7. 测试小demo

package com.ccovo.controller;

import cn.dev33.satoken.annotation.*;
import cn.dev33.satoken.stp.StpUtil;
import com.ccovo.domain.R;
import com.ccovo.domain.constants.Constants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Api(tags = "注解鉴权接口")
@RequestMapping("/annotation_auth")
public class AnnotationAuthController {

    /**
     * @SaCheckLogin: 登录校验 —— 只有登录之后才能进入该方法。
     * @SaCheckRole("admin"): 角色校验 —— 必须具有指定角色标识才能进入该方法。
     * @SaCheckPermission("user:add"): 权限校验 —— 必须具有指定权限才能进入该方法。
     * @SaCheckSafe: 二级认证校验 —— 必须二级认证之后才能进入该方法。
     * @SaCheckHttpBasic: HttpBasic校验 —— 只有通过 HttpBasic 认证后才能进入该方法。
     * @SaCheckHttpDigest: HttpDigest校验 —— 只有通过 HttpDigest 认证后才能进入该方法。
     * @SaIgnore:忽略校验 —— 表示被修饰的方法或类无需进行注解鉴权和路由拦截器鉴权。
     * @SaCheckDisable("comment"):账号服务封禁校验 —— 校验当前账号指定服务是否被封禁。
     */

    /**
     * 登录校验
     */
    @ApiOperation(value = "登录校验")
    @PostMapping("/checkLogin")
    @SaCheckLogin
    public R<?> checkLogin() {
        return R.ok();
    }

    /**
     * 角色校验
     */
    @ApiOperation(value = "角色校验")
    @PostMapping("/checkRole")
    @SaCheckRole(Constants.ADMIN)
    public R<?> checkRole() {
        return R.ok();
    }

    /**
     * 权限校验
     */
    @ApiOperation(value = "权限校验")
    @PostMapping("/checkPermission")
    @SaCheckPermission("user.add")
    public R<?> checkPermission() {
        return R.ok();
    }

    /**
     * 二级认证校验
     */
    @ApiOperation(value = "二级认证校验")
    @PostMapping("/checkSafe")
    @SaCheckSafe()
    public R<?> checkSafe() {
        return R.ok();
    }

    /**
     * Http Basic 校验
     */
    @ApiOperation(value = "Http Basic 校验")
    @PostMapping("/checkHttpBasic")
    // 账号密码:sa:123456
    @SaCheckHttpBasic(account = "sa:123456")
    public R<?> checkHttpBasic() {
        return R.ok();
    }

    /**
     * Http Digest 校验
     */
    @ApiOperation(value = "Http Digest 校验")
    @PostMapping("/checkHttpDigest")
    // 账号密码:sa:123456
    @SaCheckHttpDigest(value = "sa:123456")
    public R<?> checkHttpDigest() {
        return R.ok();
    }

    /**
     * 校验当前账号是否封禁"comment"服务
     */
    @ApiOperation(value = "校验当前账号是否封禁\"comment\"服务")
    @PostMapping("/checkDisable")
    @SaCheckDisable("comment")
    public R<?> checkDisable() {
        return R.ok();
    }

    /**
     * 权限校验(OR)
     */
    @ApiOperation(value = "权限校验(OR)")
    @PostMapping("/checkPermissionOr")
    @SaCheckPermission(value = {"user.add", "user.edit"}, mode = SaMode.OR)
    public R<?> checkPermissionOr() {
        return R.ok();
    }

    /**
     * 权限校验(AND)
     */
    @ApiOperation(value = "权限校验(AND)")
    @PostMapping("/checkPermissionAnd")
    @SaCheckPermission(value = {"user.add", "user.edit"}, mode = SaMode.AND)
    public R<?> checkPermissionAnd() {
        return R.ok();
    }

    /**
     * 角色权限双重OR校验
     * orRole 字段代表权限校验未通过时的次要选择,两者只要其一校验成功即可进入请求方法,其有三种写法:
     * 写法一:orRole = "admin",代表需要拥有角色 admin 。
     * 写法二:(OR) orRole = {"admin", "manager", "staff"},代表具有三个角色其一即可。
     * 写法三:(AND) orRole = {"admin, manager, staff"},代表必须同时具有三个角色。
     */
    @ApiOperation(value = "角色权限双重OR校验")
    @PostMapping("/checkPermissionOrRole")
    @SaCheckPermission(value = "user.add", orRole = Constants.ADMIN)
    public R<?> checkRoleOr() {
        return R.ok();
    }

    /**
     * 忽略认证
     * @SaIgnore 修饰方法时代表这个方法可以被游客访问,修饰类时代表这个类中的所有接口都可以游客访问。
     * @SaIgnore 具有最高优先级,当 @SaIgnore 和其它鉴权注解一起出现时,其它鉴权注解都将被忽略。
     * @SaIgnore 同样可以忽略掉 Sa-Token 拦截器中的路由鉴权
     */
    @ApiOperation(value = "忽略认证")
    @PostMapping("/ignore")
    @SaIgnore
    public R<?> ignore() {
        return R.ok();
    }

    /**
     * 批量注解鉴权
     */
    @ApiOperation(value = "批量注解鉴权")
    @PostMapping("/batch")
    @SaCheckOr(
            login = @SaCheckLogin,
            role = @SaCheckRole(Constants.ADMIN),
            permission = @SaCheckPermission("user.add"),
            safe = @SaCheckSafe("update-password"),
            httpBasic = @SaCheckHttpBasic(account = "sa:123456"),
            disable = @SaCheckDisable("submit-orders")
    )
    public R<?> batch() {
        return R.ok();
    }



}

eturn R.ok();
}

/**
 * 批量注解鉴权
 */
@ApiOperation(value = "批量注解鉴权")
@PostMapping("/batch")
@SaCheckOr(
        login = @SaCheckLogin,
        role = @SaCheckRole(Constants.ADMIN),
        permission = @SaCheckPermission("user.add"),
        safe = @SaCheckSafe("update-password"),
        httpBasic = @SaCheckHttpBasic(account = "sa:123456"),
        disable = @SaCheckDisable("submit-orders")
)
public R<?> batch() {
    return R.ok();
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值