mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-05 17:37:53 +08:00
新增代码示例
This commit is contained in:
parent
756b534488
commit
0009fdfdd8
@ -0,0 +1,112 @@
|
||||
package com.pj.cases;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* Sa-Token 权限认证示例
|
||||
*
|
||||
* @author kong
|
||||
* @since 2022-10-13
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/jur/")
|
||||
public class JurAuthController {
|
||||
|
||||
/*
|
||||
* 前提1:首先调用登录接口进行登录,代码在 com.pj.cases.LoginAuthController 中有详细解释,此处不再赘述
|
||||
* ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
*
|
||||
* 前提2:项目实现 StpInterface 接口,代码在 com.pj.satoken.StpInterfaceImpl
|
||||
* Sa-Token 将从此实现类获取 每个账号拥有哪些权限。
|
||||
*
|
||||
* 然后我们就可以使用以下示例中的代码进行鉴权了
|
||||
*/
|
||||
|
||||
// 查询权限 ---- http://localhost:8081/jur/getPermission
|
||||
@RequestMapping("getPermission")
|
||||
public SaResult getPermission() {
|
||||
// 查询权限信息 ,如果当前会话未登录,会返回一个空集合
|
||||
List<String> permissionList = StpUtil.getPermissionList();
|
||||
System.out.println("当前登录账号拥有的所有权限:" + permissionList);
|
||||
|
||||
// 查询角色信息 ,如果当前会话未登录,会返回一个空集合
|
||||
List<String> roleList = StpUtil.getRoleList();
|
||||
System.out.println("当前登录账号拥有的所有角色:" + roleList);
|
||||
|
||||
// 返回给前端
|
||||
return SaResult.ok()
|
||||
.set("roleList", roleList)
|
||||
.set("permissionList", permissionList);
|
||||
}
|
||||
|
||||
// 权限校验 ---- http://localhost:8081/jur/checkPermission
|
||||
@RequestMapping("checkPermission")
|
||||
public SaResult checkPermission() {
|
||||
|
||||
// 判断:当前账号是否拥有一个权限,返回 true 或 false
|
||||
// 如果当前账号未登录,则永远返回 false
|
||||
StpUtil.hasPermission("user.add");
|
||||
StpUtil.hasPermissionAnd("user.add", "user.delete", "user.get"); // 指定多个,必须全部拥有才会返回 true
|
||||
StpUtil.hasPermissionOr("user.add", "user.delete", "user.get"); // 指定多个,只要拥有一个就会返回 true
|
||||
|
||||
// 校验:当前账号是否拥有一个权限,校验不通过时会抛出 `NotPermissionException` 异常
|
||||
// 如果当前账号未登录,则永远校验失败
|
||||
StpUtil.checkPermission("user.add");
|
||||
StpUtil.checkPermissionAnd("user.add", "user.delete", "user.get"); // 指定多个,必须全部拥有才会校验通过
|
||||
StpUtil.checkPermissionOr("user.add", "user.delete", "user.get"); // 指定多个,只要拥有一个就会校验通过
|
||||
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
// 角色校验 ---- http://localhost:8081/jur/checkRole
|
||||
@RequestMapping("checkRole")
|
||||
public SaResult checkRole() {
|
||||
|
||||
// 判断:当前账号是否拥有一个角色,返回 true 或 false
|
||||
// 如果当前账号未登录,则永远返回 false
|
||||
StpUtil.hasRole("admin");
|
||||
StpUtil.hasRoleAnd("admin", "ceo", "cfo"); // 指定多个,必须全部拥有才会返回 true
|
||||
StpUtil.hasRoleOr("admin", "ceo", "cfo"); // 指定多个,只要拥有一个就会返回 true
|
||||
|
||||
// 校验:当前账号是否拥有一个角色,校验不通过时会抛出 `NotRoleException` 异常
|
||||
// 如果当前账号未登录,则永远校验失败
|
||||
StpUtil.checkRole("admin");
|
||||
StpUtil.checkRoleAnd("admin", "ceo", "cfo"); // 指定多个,必须全部拥有才会校验通过
|
||||
StpUtil.checkRoleOr("admin", "ceo", "cfo"); // 指定多个,只要拥有一个就会校验通过
|
||||
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
// 权限通配符 ---- http://localhost:8081/jur/wildcardPermission
|
||||
@RequestMapping("wildcardPermission")
|
||||
public SaResult wildcardPermission() {
|
||||
|
||||
// 前提条件:在 StpInterface 实现类中,为账号返回了 "art.*" 泛权限
|
||||
StpUtil.hasPermission("art.add"); // 返回 true
|
||||
StpUtil.hasPermission("art.delete"); // 返回 true
|
||||
StpUtil.hasPermission("goods.add"); // 返回 false,因为前缀不符合
|
||||
|
||||
// * 符合可以出现在任意位置,比如权限码的开头,当账号拥有 "*.delete" 时
|
||||
StpUtil.hasPermission("goods.add"); // false
|
||||
StpUtil.hasPermission("goods.delete"); // true
|
||||
StpUtil.hasPermission("art.delete"); // true
|
||||
|
||||
// 也可以出现在权限码的中间,比如当账号拥有 "shop.*.user" 时
|
||||
StpUtil.hasPermission("shop.add.user"); // true
|
||||
StpUtil.hasPermission("shop.delete.user"); // true
|
||||
StpUtil.hasPermission("shop.delete.goods"); // false,因为后缀不符合
|
||||
|
||||
// 注意点:
|
||||
// 1、上帝权限:当一个账号拥有 "*" 权限时,他可以验证通过任何权限码
|
||||
// 2、角色校验也可以加 * ,指定泛角色,例如: "*.admin",暂不赘述
|
||||
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.pj.cases;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* Sa-Token 权限认证示例
|
||||
*
|
||||
* @author kong
|
||||
* @since 2022-10-13
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/kickout/")
|
||||
public class KickoutController {
|
||||
|
||||
/*
|
||||
* 前提:首先调用登录接口进行登录,代码在 com.pj.cases.LoginAuthController 中有详细解释,此处不再赘述
|
||||
*/
|
||||
|
||||
// 将指定账号强制注销 ---- http://localhost:8081/kickout/logout?userId=10001
|
||||
@RequestMapping("logout")
|
||||
public SaResult logout(long userId) {
|
||||
|
||||
// 强制注销等价于对方主动调用了注销方法,再次访问会提示:Token无效。
|
||||
StpUtil.logout(userId);
|
||||
|
||||
// 返回
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
// 将指定账号踢下线 ---- http://localhost:8081/kickout/kickout?userId=10001
|
||||
@RequestMapping("kickout")
|
||||
public SaResult kickout(long userId) {
|
||||
|
||||
// 踢人下线不会清除Token信息,而是将其打上特定标记,再次访问会提示:Token已被踢下线。
|
||||
StpUtil.kickout(userId);
|
||||
|
||||
// 返回
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
/*
|
||||
* 你可以分别在强制注销和踢人下线后,再次访问一下登录校验接口,对比一下两者返回的提示信息有何不同
|
||||
* ---- http://localhost:8081/acc/checkLogin
|
||||
*/
|
||||
|
||||
// 根据 Token 值踢人 ---- http://localhost:8081/kickout/kickoutByTokenValue?tokenValue=xxxx-xxxx-xxxx-xxxx已登录账号的token值
|
||||
public SaResult kickoutByTokenValue(String tokenValue) {
|
||||
|
||||
StpUtil.kickoutByTokenValue(tokenValue);
|
||||
|
||||
// 返回
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -3,47 +3,137 @@ package com.pj.cases;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.stp.SaTokenInfo;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* 登录认证示例
|
||||
* Sa-Token 登录认证示例
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
* @since 2022-10-13
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/acc/")
|
||||
public class LoginAuthController {
|
||||
|
||||
// 测试登录 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
// 会话登录接口 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
@RequestMapping("doLogin")
|
||||
public SaResult doLogin(String name, String pwd) {
|
||||
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||
|
||||
// 第一步:比对前端提交的 账号名称 & 密码 是否正确,比对成功后开始登录
|
||||
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||
if("zhang".equals(name) && "123456".equals(pwd)) {
|
||||
|
||||
// 第二步:根据账号id,进行登录
|
||||
// 此处填入的参数应该保持用户表唯一,比如用户id,不可以直接填入整个 User 对象
|
||||
StpUtil.login(10001);
|
||||
|
||||
// SaResult 是 Sa-Token 中对返回结果的简单封装,下面的示例将不再赘述
|
||||
return SaResult.ok("登录成功");
|
||||
}
|
||||
|
||||
return SaResult.error("登录失败");
|
||||
}
|
||||
|
||||
// 查询登录状态 ---- http://localhost:8081/acc/isLogin
|
||||
// 查询当前登录状态 ---- http://localhost:8081/acc/isLogin
|
||||
@RequestMapping("isLogin")
|
||||
public SaResult isLogin() {
|
||||
return SaResult.ok("是否登录:" + StpUtil.isLogin());
|
||||
// StpUtil.isLogin() 查询当前客户端是否登录,返回 true 或 false
|
||||
boolean isLogin = StpUtil.isLogin();
|
||||
return SaResult.ok("当前客户端是否登录:" + isLogin);
|
||||
}
|
||||
|
||||
// 校验当前登录状态 ---- http://localhost:8081/acc/checkLogin
|
||||
@RequestMapping("checkLogin")
|
||||
public SaResult checkLogin() {
|
||||
// 检验当前会话是否已经登录, 如果未登录,则抛出异常:`NotLoginException`
|
||||
StpUtil.checkLogin();
|
||||
|
||||
// 抛出异常后,代码将走入全局异常处理(GlobalException.java),如果没有抛出异常,则代表通过了登录校验,返回下面信息
|
||||
return SaResult.ok("校验登录成功,这行字符串是只有登录后才会返回的信息");
|
||||
}
|
||||
|
||||
// 获取当前登录的账号是谁 ---- http://localhost:8081/acc/getLoginId
|
||||
@RequestMapping("getLoginId")
|
||||
public SaResult getLoginId() {
|
||||
// 需要注意的是,StpUtil.getLoginId() 自带登录校验效果
|
||||
// 也就是说如果在未登录的情况下调用这句代码,框架就会抛出 `NotLoginException` 异常,效果和 StpUtil.checkLogin() 是一样的
|
||||
Object userId = StpUtil.getLoginId();
|
||||
System.out.println("当前登录的账号id是:" + userId);
|
||||
|
||||
// 如果不希望 StpUtil.getLoginId() 触发登录校验效果,可以填入一个默认值
|
||||
// 如果会话未登录,则返回这个默认值,如果会话已登录,将正常返回登录的账号id
|
||||
Object userId2 = StpUtil.getLoginId(0);
|
||||
System.out.println("当前登录的账号id是:" + userId2);
|
||||
|
||||
// 或者使其在未登录的时候返回 null
|
||||
Object userId3 = StpUtil.getLoginIdDefaultNull();
|
||||
System.out.println("当前登录的账号id是:" + userId3);
|
||||
|
||||
// 类型转换:
|
||||
// StpUtil.getLoginId() 返回的是 Object 类型,你可以使用以下方法指定其返回的类型
|
||||
int userId4 = StpUtil.getLoginIdAsInt(); // 将返回值转换为 int 类型
|
||||
long userId5 = StpUtil.getLoginIdAsLong(); // 将返回值转换为 long 类型
|
||||
String userId6 = StpUtil.getLoginIdAsString(); // 将返回值转换为 String 类型
|
||||
|
||||
// 疑问:数据基本类型不是有八个吗,为什么只封装以上三种类型的转换?
|
||||
// 因为大多数项目都是拿 int、long 或 String 声明 UserId 的类型的,实在没见过哪个项目用 double、float、boolean 之类来声明 UserId
|
||||
System.out.println("当前登录的账号id是:" + userId4 + " --- " + userId5 + " --- " + userId6);
|
||||
|
||||
// 返回给前端
|
||||
return SaResult.ok("当前客户端登录的账号id是:" + userId);
|
||||
}
|
||||
|
||||
// 查询 Token 信息 ---- http://localhost:8081/acc/tokenInfo
|
||||
@RequestMapping("tokenInfo")
|
||||
public SaResult tokenInfo() {
|
||||
// TokenName 是 Token 名称的意思,此值也决定了前端提交 Token 时应该使用的参数名称
|
||||
String tokenName = StpUtil.getTokenName();
|
||||
System.out.println("前端提交 Token 时应该使用的参数名称:" + tokenName);
|
||||
|
||||
// 使用 StpUtil.getTokenValue() 获取前端提交的 Token 值
|
||||
// 框架默认前端可以从以下三个途径中提交 Token:
|
||||
// Cookie (浏览器自动提交)
|
||||
// Header头 (代码手动提交)
|
||||
// Query 参数 (代码手动提交) 例如: /user/getInfo?satoken=xxxx-xxxx-xxxx-xxxx
|
||||
// 读取顺序为: Query 参数 --> Header头 -- > Cookie
|
||||
// 以上三个地方都读取不到 Token 信息的话,则视为前端没有提交 Token
|
||||
String tokenValue = StpUtil.getTokenValue();
|
||||
System.out.println("前端提交的Token值为:" + tokenValue);
|
||||
|
||||
// TokenInfo 包含了此 Token 的大多数信息
|
||||
SaTokenInfo info = StpUtil.getTokenInfo();
|
||||
System.out.println("Token 名称:" + info.getTokenName());
|
||||
System.out.println("Token 值:" + info.getTokenValue());
|
||||
System.out.println("当前是否登录:" + info.getIsLogin());
|
||||
System.out.println("当前登录的账号id:" + info.getLoginId());
|
||||
System.out.println("当前登录账号的类型:" + info.getLoginType());
|
||||
System.out.println("当前登录客户端的设备类型:" + info.getLoginDevice());
|
||||
System.out.println("当前 Token 的剩余有效期:" + info.getTokenTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在
|
||||
System.out.println("当前 Token 的剩余临时有效期:" + info.getTokenActivityTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在
|
||||
System.out.println("当前 User-Session 的剩余有效期" + info.getSessionTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在
|
||||
System.out.println("当前 Token-Session 的剩余有效期" + info.getTokenSessionTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在
|
||||
|
||||
// 返回给前端
|
||||
return SaResult.data(StpUtil.getTokenInfo());
|
||||
}
|
||||
|
||||
// 测试注销 ---- http://localhost:8081/acc/logout
|
||||
// 会话注销 ---- http://localhost:8081/acc/logout
|
||||
@RequestMapping("logout")
|
||||
public SaResult logout() {
|
||||
// 退出登录会清除三个地方的数据:
|
||||
// 1、Redis中保存的 Token 信息
|
||||
// 2、当前请求上下文中保存的 Token 信息
|
||||
// 3、Cookie 中保存的 Token 信息(如果未使用Cookie模式则不会清除)
|
||||
StpUtil.logout();
|
||||
return SaResult.ok();
|
||||
|
||||
// StpUtil.logout() 在未登录时也是可以调用成功的,
|
||||
// 也就是说,无论客户端有没有登录,执行完 StpUtil.logout() 后,都会处于未登录状态
|
||||
System.out.println("当前是否处于登录状态:" + StpUtil.isLogin());
|
||||
|
||||
// 返回给前端
|
||||
return SaResult.ok("退出登录成功");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package com.pj.current;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.exception.NotPermissionException;
|
||||
import cn.dev33.satoken.exception.NotRoleException;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
@ -11,9 +14,9 @@ import cn.dev33.satoken.util.SaResult;
|
||||
@RestControllerAdvice
|
||||
public class GlobalException {
|
||||
|
||||
// 全局异常拦截
|
||||
@ExceptionHandler
|
||||
public SaResult handlerException(Exception e) {
|
||||
// 拦截:未登录异常
|
||||
@ExceptionHandler(NotLoginException.class)
|
||||
public SaResult handlerException(NotLoginException e) {
|
||||
|
||||
// 打印堆栈,以供调试
|
||||
e.printStackTrace();
|
||||
@ -21,5 +24,26 @@ public class GlobalException {
|
||||
// 返回给前端
|
||||
return SaResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
// 拦截:缺少权限异常
|
||||
@ExceptionHandler(NotPermissionException.class)
|
||||
public SaResult handlerException(NotPermissionException e) {
|
||||
e.printStackTrace();
|
||||
return SaResult.error("缺少权限:" + e.getPermission());
|
||||
}
|
||||
|
||||
// 拦截:缺少角色异常
|
||||
@ExceptionHandler(NotRoleException.class)
|
||||
public SaResult handlerException(NotRoleException e) {
|
||||
e.printStackTrace();
|
||||
return SaResult.error("缺少角色:" + e.getRole());
|
||||
}
|
||||
|
||||
// 拦截:其它所有异常
|
||||
@ExceptionHandler(Exception.class)
|
||||
public SaResult handlerException(Exception e) {
|
||||
e.printStackTrace();
|
||||
return SaResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,10 @@ import org.springframework.stereotype.Component;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
|
||||
/**
|
||||
* 自定义权限验证接口扩展
|
||||
* 自定义权限认证接口扩展,Sa-Token 将从此实现类获取每个账号拥有的权限码
|
||||
*
|
||||
* @author kong
|
||||
* @since 2022-10-13
|
||||
*/
|
||||
@Component // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展
|
||||
public class StpInterfaceImpl implements StpInterface {
|
||||
@ -21,11 +24,11 @@ public class StpInterfaceImpl implements StpInterface {
|
||||
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("101");
|
||||
list.add("user-add");
|
||||
list.add("user-delete");
|
||||
list.add("user-update");
|
||||
list.add("user-get");
|
||||
list.add("article-get");
|
||||
list.add("user.add");
|
||||
list.add("user.update");
|
||||
list.add("user.get");
|
||||
// list.add("user.delete");
|
||||
list.add("art.*");
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ body {
|
||||
|
||||
|
||||
/* 答题按钮 */
|
||||
#main .dt-btn{
|
||||
#main .dt-btn,#main .case-btn{
|
||||
background-color: #e7ecf3;
|
||||
color: #385481;
|
||||
display: inline-block;
|
||||
@ -250,20 +250,24 @@ body {
|
||||
border-radius: 1px;
|
||||
/* border-bottom-width: 0px !important; */
|
||||
|
||||
/* background-color: #f0f9eb;
|
||||
color: #42b983;
|
||||
display: inline-block;
|
||||
border: 1px #13ce66 solid; */
|
||||
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
padding: 8px 14px;
|
||||
font-size: 14px;
|
||||
transition: all 0.15s;
|
||||
|
||||
/* 背景 */
|
||||
background-image: url(icon/dati.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 20px 20px;
|
||||
background-position: 1em 50%;
|
||||
background-position: 1em 12px;
|
||||
text-indent: 2em;
|
||||
}
|
||||
/* 代码示例按钮 */
|
||||
#main .case-btn{
|
||||
background-color: #f4fdef;
|
||||
color: #42b983;
|
||||
border: 1px #c4e5b5 solid !important;
|
||||
background-size: 18px 18px;
|
||||
background-image: url(icon/code.svg);
|
||||
}
|
1
sa-token-doc/static/icon/code.svg
Normal file
1
sa-token-doc/static/icon/code.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1665596300740" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M288.256 216.064a51.2 51.2 0 0 0-72.191 8.192l-204.8 256a51.2 51.2 0 0 0 0 64l204.8 256a51.2 51.2 0 0 0 79.872-64L116.736 512l179.2-224.254a51.2 51.2 0 0 0-7.68-71.68zM1012.736 481.256l-204.8-256a51.2 51.2 0 0 0-79.872 64l179.2 223.744-179.2 224.256a51.2 51.2 0 0 0 79.872 64l204.8-256a51.2 51.2 0 0 0 0-64zM599.552 102.4a51.2 51.2 0 0 0-60.928 39.424l-153.6 716.8A51.2 51.2 0 0 0 424.448 921.6h10.752a51.2 51.2 0 0 0 51.2-40.448l153.6-716.8A51.2 51.2 0 0 0 599.552 102.4z" fill="#42b983"></path></svg>
|
After Width: | Height: | Size: 808 B |
@ -1,4 +1,10 @@
|
||||
# 权限认证
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/JurAuthController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 权限认证 —— [ sa-token-demo-case:com.pj.cases.JurAuthController.java ]
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -41,11 +47,11 @@ public class StpInterfaceImpl implements StpInterface {
|
||||
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("101");
|
||||
list.add("user-add");
|
||||
list.add("user-delete");
|
||||
list.add("user-update");
|
||||
list.add("user-get");
|
||||
list.add("article-get");
|
||||
list.add("user.add");
|
||||
list.add("user.update");
|
||||
list.add("user.get");
|
||||
// list.add("user.delete");
|
||||
list.add("art.*");
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -68,42 +74,42 @@ public class StpInterfaceImpl implements StpInterface {
|
||||
- loginId:账号id,即你在调用 `StpUtil.login(id)` 时写入的标识值。
|
||||
- loginType:账号体系标识,此处可以暂时忽略,在 [ 多账户认证 ] 章节下会对这个概念做详细的解释。
|
||||
|
||||
可参考代码:[码云:StpInterfaceImpl.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/satoken/StpInterfaceImpl.java)
|
||||
可参考代码:[码云:StpInterfaceImpl.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpInterfaceImpl.java)
|
||||
|
||||
> 注意: StpInterface 接口在需要鉴权时由框架自动调用, 开发者只需要配置好就可以使用下面的鉴权方法或后面的注解鉴权
|
||||
> 注意: StpInterface 接口在需要鉴权时由框架自动调用,开发者只需要配置好就可以使用下面的鉴权方法或后面的注解鉴权
|
||||
|
||||
|
||||
### 权限认证
|
||||
### 权限校验
|
||||
然后就可以用以下api来鉴权了
|
||||
|
||||
``` java
|
||||
// 获取:当前账号所拥有的权限集合
|
||||
StpUtil.getPermissionList();
|
||||
|
||||
// 判断:当前账号是否含有指定权限, 返回true或false
|
||||
StpUtil.hasPermission("user-update");
|
||||
// 判断:当前账号是否含有指定权限, 返回 true 或 false
|
||||
StpUtil.hasPermission("user.add");
|
||||
|
||||
// 校验:当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException
|
||||
StpUtil.checkPermission("user-update");
|
||||
StpUtil.checkPermission("user.add");
|
||||
|
||||
// 校验:当前账号是否含有指定权限 [指定多个,必须全部验证通过]
|
||||
StpUtil.checkPermissionAnd("user-update", "user-delete");
|
||||
StpUtil.checkPermissionAnd("user.add", "user.delete", "user.get");
|
||||
|
||||
// 校验:当前账号是否含有指定权限 [指定多个,只要其一验证通过即可]
|
||||
StpUtil.checkPermissionOr("user-update", "user-delete");
|
||||
StpUtil.checkPermissionOr("user.add", "user.delete", "user.get");
|
||||
```
|
||||
|
||||
扩展:`NotPermissionException` 对象可通过 `getLoginType()` 方法获取具体是哪个 `StpLogic` 抛出的异常
|
||||
|
||||
|
||||
### 角色认证
|
||||
### 角色校验
|
||||
在Sa-Token中,角色和权限可以独立验证
|
||||
|
||||
``` java
|
||||
// 获取:当前账号所拥有的角色集合
|
||||
StpUtil.getRoleList();
|
||||
|
||||
// 判断:当前账号是否拥有指定角色, 返回true或false
|
||||
// 判断:当前账号是否拥有指定角色, 返回 true 或 false
|
||||
StpUtil.hasRole("super-admin");
|
||||
|
||||
// 校验:当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException
|
||||
@ -137,22 +143,22 @@ public class GlobalExceptionHandler {
|
||||
}
|
||||
```
|
||||
|
||||
可参考:[码云:GlobalException.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/current/GlobalException.java)
|
||||
可参考:[码云:GlobalException.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/current/GlobalException.java)
|
||||
|
||||
|
||||
### 权限通配符
|
||||
Sa-Token允许你根据通配符指定**泛权限**,例如当一个账号拥有`user*`的权限时,`user-add`、`user-delete`、`user-update`都将匹配通过
|
||||
Sa-Token允许你根据通配符指定**泛权限**,例如当一个账号拥有`art.*`的权限时,`art.add`、`art.delete`、`art.update`都将匹配通过
|
||||
|
||||
``` java
|
||||
// 当拥有 user* 权限时
|
||||
StpUtil.hasPermission("user-add"); // true
|
||||
StpUtil.hasPermission("user-update"); // true
|
||||
StpUtil.hasPermission("art-add"); // false
|
||||
// 当拥有 art.* 权限时
|
||||
StpUtil.hasPermission("art.add"); // true
|
||||
StpUtil.hasPermission("art.update"); // true
|
||||
StpUtil.hasPermission("goods.add"); // false
|
||||
|
||||
// 当拥有 *-delete 权限时
|
||||
StpUtil.hasPermission("user-add"); // false
|
||||
StpUtil.hasPermission("user-delete"); // true
|
||||
StpUtil.hasPermission("art-delete"); // true
|
||||
// 当拥有 *.delete 权限时
|
||||
StpUtil.hasPermission("art.delete"); // true
|
||||
StpUtil.hasPermission("user.delete"); // true
|
||||
StpUtil.hasPermission("user.update"); // false
|
||||
|
||||
// 当拥有 *.js 权限时
|
||||
StpUtil.hasPermission("index.js"); // true
|
||||
@ -174,9 +180,9 @@ StpUtil.hasPermission("index.html"); // false
|
||||
2. 前端将权限码集合保存在`localStorage`或其它全局状态管理对象中。
|
||||
3. 在需要权限控制的按钮上,使用 js 进行逻辑判断,例如在`Vue`框架中我们可以使用如下写法:
|
||||
``` js
|
||||
<button v-if="arr.indexOf('user:delete') > -1">删除按钮</button>
|
||||
<button v-if="arr.indexOf('user.delete') > -1">删除按钮</button>
|
||||
```
|
||||
其中:`arr`是当前用户拥有的权限码数组,`user:delete`是显示按钮需要拥有的权限码,`删除按钮`是用户拥有权限码才可以看到的内容。
|
||||
其中:`arr`是当前用户拥有的权限码数组,`user.delete`是显示按钮需要拥有的权限码,`删除按钮`是用户拥有权限码才可以看到的内容。
|
||||
|
||||
|
||||
注意:以上写法只为提供一个参考示例,不同框架有不同写法,大家可根据项目技术栈灵活封装进行调用。
|
||||
|
@ -1,4 +1,10 @@
|
||||
# 登录认证
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/LoginAuthController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 登录认证 —— [ sa-token-demo-case:com.pj.cases.LoginAuthController.java ]
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -16,7 +22,7 @@
|
||||
3. 用户后续的每次请求,都携带上这个 Token。
|
||||
4. 服务器根据 Token 判断此会话是否登录成功。
|
||||
|
||||
所谓登录认证,指的就是服务器校验账号密码,为用户颁发 Token 会话凭证的过程,这个 Token 也是我们后续通过接口校验的关键所在。
|
||||
所谓登录认证,指的就是服务器校验账号密码,为用户颁发 Token 会话凭证的过程,这个 Token 也是我们后续判断会话是否登录的关键所在。
|
||||
|
||||
|
||||
<button class="show-img" img-src="https://oss.dev33.cn/sa-token/doc/g/g3--login-auth.gif">加载动态演示图</button>
|
||||
|
Loading…
Reference in New Issue
Block a user