v1.4.0更新

This commit is contained in:
shengzhang
2020-09-07 02:21:35 +08:00
parent 61647a2bba
commit 167cff595e
51 changed files with 624 additions and 500 deletions

View File

@@ -1,12 +1,25 @@
# sa-token
<p align="center">
<img alt="logo" src="http://sa-token.dev33.cn/doc/logo.png" width="150" height="150" style="margin-bottom: 10px;">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">sa-token v1.4.0</h1>
<h4 align="center">一个JavaWeb权限认证框架强大、简单、好用</h4>
<h4 align="center">
<a href="https://github.com/click33/sa-token"><img src="https://img.shields.io/badge/sa--token-v1.4.0-2B9939"></a>
<a href="https://github.com/click33/sa-token"><img src="https://img.shields.io/badge/language-java-2B9939"></a>
<a href="https://github.com/click33/sa-token/stargazers"><img src="https://img.shields.io/github/stars/click33/sa-token"></a>
<a href="https://github.com/click33/sa-token/watchers"><img src="https://img.shields.io/github/watchers/click33/sa-token"></a>
<a href="https://github.com/click33/sa-token/network/members"><img src="https://img.shields.io/github/forks/click33/sa-token"></a>
<a href="https://github.com/click33/sa-token/issues"><img src="https://img.shields.io/github/issues/click33/sa-token.svg"></a>
<a href="https://github.com/click33/sa-token/blob/master/LICENSE"><img src="https://img.shields.io/github/license/click33/sa-token.svg"></a>
</h4>
一个JavaWeb权限认证框架强大、简单、好用
在线文档:[http://sa-token.dev33.cn/](http://sa-token.dev33.cn/)
---
## sa-token 😋
- 在线文档:[http://sa-token.dev33.cn/](http://sa-token.dev33.cn/)
- 需求提交:我们深知一个优秀的项目需要海纳百川,[点我在线提交需求](http://sa-app.dev33.cn/wall.html?name=sa-token)
:kissing_closed_eyes: :kissing_closed_eyes: :kissing_closed_eyes: :yum: :yum: :yum: :innocent: :innocent: :innocent: :heart: :heart: :heart:
## 优点
## 框架优点
与其它权限认证框架相比sa-token尽力保证两点
- 上手简单:能自动化的配置全部自动化,不让你费脑子
- 功能强大:能涵盖的功能全部涵盖,不让你用个框架还要自己给框架打各种补丁
@@ -24,9 +37,6 @@
- 零配置与Spring等框架集成
- ...
## 需求提交
- 我们深知一个优秀的项目需要海纳百川,[点我在线提交需求](http://sa-app.dev33.cn/wall.html?name=sa-token)
## 贡献代码
1. 在github上fork一份到自己的仓库
2. clone自己的仓库到本地电脑

View File

@@ -28,7 +28,7 @@
<div id="app">加载中...</div>
<script>
var name = '<img style="width: 50px; height: 50px; vertical-align: middle;" src="logo.png" alt="logo" /> ';
name += '<b style="font-size: 24px; vertical-align: middle;">sa-token</b> <sub>v1.0.3</sub>'
name += '<b style="font-size: 24px; vertical-align: middle;">sa-token</b> <sub>v1.4.0</sub>'
window.$docsify = {
name: name, // 名字
repo: 'https://github.com/click33/sa-token', // github地址

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -4,7 +4,7 @@
- **sa-admin**[一个多窗口后台模板,流畅、易上手、提高生产力](http://sa-admin.dev33.cn/)
- **sa-vue-admin**[对sa-admin的vue单页版实现, 基于vue-cli、element-ui的单页后台模板](http://sa-vue-admin.dev33.cn/)
- **sa-fast**[一个基于springboot架构的快速开发平台内置代码生成器吹灰之力快速CRUD](http://sa-fast.dev33.cn/)
- **sa-plus**[一个基于springboot架构的快速开发平台内置代码生成器吹灰之力快速CRUD](http://sa-plus.dev33.cn/)
- **sa-doc**[一个基于markdown的接口文档编写工具](http://sa-doc.dev33.cn/)
- **SqlFly**[一个java语言的ORM框架](https://sqlfly.dev33.cn/)
- 虚位以待

View File

@@ -1,10 +1,17 @@
# 更新日志
### 2020-9-7 @v1.4.0
- 优化修改一些函数、变量名称使其更符合阿里java代码规范
- 优化:`tokenValue`的读取优先级改为:`request` > `body` > `header` > `cookie`
- 新增:新增`isReadCookie`配置,决定是否从`cookie`里读取`token`信息
- 优化:如果`isReadCookie`配置为`false`,那么在登录时也不会把`cookie`写入`cookie`
- 新增:新增`getSessionByLoginId(Object loginId, boolean isCreate)`方法
- 修复:修复文档部分错误,修正群号码
### 2020-5-2 @v1.0.3
- 新增:新增 `StpUtil.checkLogin()` 方法,更符合语义化的鉴权方法
- 新增:注册拦截器时可设置 `StpLogic` ,方便不同模块不同鉴权方式
- 新增:抛出异常时增加 `login_key` 区分,方便多账号体系鉴权处理
- 新增:抛出异常时增加 `loginKey` 区分,方便多账号体系鉴权处理
- 修复修复启动时的版本字符画版本号打印不对的bug
- 修复:修复文档部分不正确之处
- 新增:新增文档的友情链接
@@ -14,7 +21,7 @@
- 参考:[注解式验证](use/at-check)
### 2020-2-12 @v1.0.1
- 修复:修复`StpUtil.getLoginId(T default_value)`取值转换错误的bug
- 修复:修复`StpUtil.getLoginId(T defaultValue)`取值转换错误的bug
### 2020-2-4 @v1.0.0
- 第一个版本出炉

View File

@@ -9,18 +9,18 @@
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token</artifactId>
<version>1.0.3</version>
<version>1.4.0</version>
</dependency>
```
## 源码
## 获取源码
如果你想深入了解`sa-token`,你可以通过`github`或者`gitee`来获取源码
- github地址[https://github.com/click33/sa-token](https://github.com/click33/sa-token)
- gitee地址[https://gitee.com/sz6/sa-token](https://gitee.com/sz6/sa-token)
- 开源不易求鼓励给个star吧
- 开源不易,求鼓励,给个`star`
- 源码目录介绍
- sa-token-dev: 源码
- sa-token-demo-springboot: springboot集成示例
@@ -29,7 +29,7 @@
## jar包下载
[点击下载sa-token-1.0.3.jar](https://color-test.oss-cn-qingdao.aliyuncs.com/sa-token/sa-token-1.0.3.jar)
[点击下载sa-token-1.4.0.jar](https://color-test.oss-cn-qingdao.aliyuncs.com/sa-token/sa-token-1.4.0.jar)

View File

@@ -18,7 +18,7 @@
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token</artifactId>
<version>1.0.3</version>
<version>1.4.0</version>
</dependency>
```

View File

@@ -3,7 +3,7 @@
- 尽管我们可以方便的一句代码完成权限验证,但是有时候我们仍希望可以将鉴权代码与我们的业务代码分离开来
- 怎么做?
- sa-token内置两个注解帮助你使用注解完成鉴权操作
- `sa-token`内置两个注解,帮助你使用注解完成鉴权操作
## 1、注册拦截器
@@ -21,7 +21,7 @@
}
}
```
- 保证此类被springboot启动类扫描到
- 保证此类被`springboot`启动类扫描到
## 2、使用注解

View File

@@ -1,17 +1,18 @@
# 框架配置
- 你可以零配置启动框架
- 但同时你也可以通过配置定制性使用框架sa-token支持多种方式配置框架信息
- 但同时你也可以通过配置,定制性使用框架,`sa-token`支持多种方式配置框架信息
---
### 所有可配置项
| 参数名称 | 类型 | 默认值 | 说明 |
| :-------- | :-------- | :-------- | :-------- |
| tokenName | String | satoken | token名称同时也是cookie名称 |
| timeout | long | 2592000 | token有效期单位s 默认30天 |
| isShare | Boolean | true | 在多人登录同一账号时是否共享会话为true时共用一个为false时新登录挤掉旧登录 |
| isReadHead| Boolean | true | 是否在cookie读取不到token时继续从请求header里继续尝试读取 |
| isReadBody| Boolean | true | 是否header读取不到token时,继续从请求题参数里继续尝试读取 |
| isV | Boolean | true | 是否在初始化配置时打印版本字符画 |
| 参数名称 | 类型 | 默认值 | 说明 |
| :-------- | :-------- | :-------- | :-------- |
| tokenName | String | satoken | token名称同时也是cookie名称 |
| timeout | long | 2592000 | token有效期单位s 默认30天 |
| isShare | Boolean | true | 在多人登录同一账号时是否共享会话为true时共用一个为false时新登录挤掉旧登录|
| isReadBody | Boolean | true | 是否尝试从请求体里读取token |
| isReadHead | Boolean | true | 是否尝试从header读取token |
| isReadCookie | Boolean | true | 是否尝试从cookie里读取token |
| isV | Boolean | true | 是否在初始化配置时打印版本字符画 |
@@ -25,16 +26,17 @@
@Configuration
public class MySaTokenConfig {
// 获取配置Bean
// 获取配置Bean (以代码的方式配置sa-token)
@Primary
@Bean(name="MySaTokenConfig")
public SaTokenConfig getSaTokenConfig() {
SaTokenConfig config = new SaTokenConfig();
config.setTokenName("satoken"); // token名称同时也是cookie名称
config.setTokenName("satoken"); // token名称 (同时也是cookie名称)
config.setTimeout(30 * 24 * 60 * 60); // token有效期单位s 默认30天
config.setIsShare(true); // 在多人登录同一账号时,是否共享会话为true时共用一个为false时新登录挤掉旧登录
config.setIsReadHead(true); // 是否在cookie读取不到token时继续从请求header里继续尝试读取
config.setIsReadBody(true); // 是否在cookie读取不到token时继续从请求header里继续尝试读取
config.setIsShare(true); // 在多人登录同一账号时,是否共享会话 (为true时共用一个为false时新登录挤掉旧登录)
config.setIsReadBody(true); // 是否尝试从请求体里读取token
config.setIsReadHead(true); // 是否尝试从header里读取token
config.setIsReadCookie(true); // 是否尝试从cookie里读取token
config.setIsV(true); // 是否在初始化配置时打印版本字符画
return config;
}
@@ -48,16 +50,18 @@
spring:
# sa-token配置
sa-token:
# token名称同时也是cookie名称
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天
timeout: 2592000
# 在多人登录同一账号时,是否共享会话为true时共用一个为false时新登录挤掉旧登录
# 在多人登录同一账号时,是否共享会话 (为true时共用一个为false时新登录挤掉旧登录)
is-share: true
# 是否在cookie读取不到token时继续从请求header里继续尝试读取
is-read-head: true
# 是否在header读取不到token时继续从请求题参数里继续尝试读取
# 是否尝试从请求体里读取token
is-read-body: true
# 是否尝试从header里读取token
is-read-head: true
# 是否尝试从cookie里读取token
is-read-cookie: true
# 是否在初始化配置时打印版本字符画
is-v: true
```

View File

@@ -1,6 +1,6 @@
# 持久层扩展
---
- 每次重启项目就得重新登录一遍我想把登录数据都放在redis里这样重启项目也不用重新登录行不行
- 每次重启项目就得重新登录一遍,我想把登录数据都放在`redis`里,这样重启项目也不用重新登录,行不行?
- 行!
- 你需要做的就是重写`sa-token`的dao层实现方式参考以下方案

View File

@@ -32,7 +32,7 @@ public class StpInterfaceImpl implements StpInterface {
// 返回一个账号所拥有的权限码集合
@Override
public List<Object> getPermissionCodeList(Object login_id, String login_key) {
public List<Object> getPermissionCodeList(Object loginId, String loginKey) {
List<Object> list = new ArrayList<Object>(); // 本list仅做模拟实际项目中要根据具体业务逻辑来查询权限
list.add("101");
list.add("user-add");

View File

@@ -4,12 +4,12 @@
## 核心思想
- 所谓踢人下线核心操作就是找到其指定login_id的token并设置其失效
- 所谓踢人下线,核心操作就是找到其指定`loginId`的token并设置其失效
## 具体API
#### StpUtil.logoutByLoginId(Object login_id)
- 让指定login_id的会话注销登录踢人下线
#### StpUtil.logoutByLoginId(Object loginId)
- 让指定loginId的会话注销登录踢人下线

View File

@@ -12,9 +12,9 @@
## 具体API
#### StpUtil.setLoginId(Object login_id)
#### StpUtil.setLoginId(Object loginId)
- 标记当前会话登录的账号id
- 建议的参数类型long | int | String 不可以传入复杂类型UserAdmin等等
- 建议的参数类型:`long | int | String` 不可以传入复杂类型,如:`User``Admin`等等
#### StpUtil.logout()
- 当前会话注销登录
@@ -29,12 +29,12 @@
#### StpUtil.getLoginId()
- 获取当前会话登录id, 如果未登录,则抛出异常:`NotLoginException`
- 类似API还有
- `StpUtil.getLoginId_asString()` 获取当前会话登录id, 并转化为String类型
- `StpUtil.getLoginId_asInt()` 获取当前会话登录id, 并转化为int类型
- `StpUtil.getLoginId_asLong()` 获取当前会话登录id, 并转化为long类型
- `StpUtil.getLoginIdAsString()` 获取当前会话登录id, 并转化为`String`类型
- `StpUtil.getLoginIdAsInt()` 获取当前会话登录id, 并转化为`int`类型
- `StpUtil.getLoginIdAsLong()` 获取当前会话登录id, 并转化为`long`类型
#### StpUtil.getLoginId(T default_value)
- 获取当前会话登录id, 如果未登录,则返回默认值 default_value可以为任意类型
#### StpUtil.getLoginId(T defaultValue)
- 获取当前会话登录id, 如果未登录,则返回默认值 `defaultValue`可以为任意类型)
- 类似API还有
- `StpUtil.getLoginId_defaultNull()` 获取当前会话登录id, 如果未登录则返回null

View File

@@ -2,7 +2,7 @@
---
## 问题
- 有的时候在一个项目中我们会设计两套账号体系比如一个商城的user表admin表
- 有的时候在一个项目中,我们会设计两套账号体系,比如一个商城的`user表``admin表`
- 这时候,我们就需要将两套账号的权限认证分开,防止冲突
@@ -12,16 +12,16 @@
- 就会发现,此类并没有任何代码逻辑,唯一做的事就是对成员变量`stpLogic`的各个API进行包装一下进行转发
- 这样做有两个优点
- `StpLogic`类的所有函数都可以被重写,按需扩展
- 在构造方法时随意传入一个不同的 `login_key`,就可以再造一套账号登录体系
- 在构造方法时随意传入一个不同的 `loginKey`,就可以再造一套账号登录体系
## 操作示例
比如说,对于`StpUtil`类,我们只做`admin账号`权限验证,而对于`user账号`,我们则:
1. 新建一个新的权限验证类,比如: `StpUserUtil.java`
2.`StpUtil.java`类的全部代码复制粘贴到 `StpUserUtil.java`
3. 更改一下其 `login_key` 比如:
3. 更改一下其 `loginKey` 比如:
```
// 底层的 StpLogic 对象
public static StpLogic stpLogic = new StpLogic("user"); // login_key改为user
public static StpLogic stpLogic = new StpLogic("user"); // loginKey改为user
```
4. 接下来就可以像调用`StpUtil.java`一样调用 `StpUserUtil.java`了,这两套账号认证的逻辑是完全隔离的

View File

@@ -2,23 +2,25 @@
---
- 以上介绍的api都是操作当前账号对当前账号进行各种鉴权操作你可能会问我能不能对别的账号进行一些操作
- 比如查看账号10001有无某个权限码、获取id账号为10002的用户session等等...
- 比如:查看账号`10001`有无某个权限码、获取id账号为`10002`的用户`session`,等等...
- `sa-token`在api设计时充分考虑了这一点暴露出多个api进行此类操作
## 有关操作其它账号的api
#### StpUtil.getTokenValueByLoginId(Object login_id)
- 获取指定login_id的tokenValue值
#### StpUtil.getTokenValueByLoginId(Object loginId)
- 获取指定`loginId``tokenValue`
#### StpUtil.logoutByLoginId(Object login_id)
- 指定login_id的会话注销登录(踢人下线)
#### StpUtil.logoutByLoginId(Object loginId)
- 指定`loginId`的会话注销登录(踢人下线)
#### StpUtil.getSessionByLoginId(Object login_id)
- 获取指定login_id的session
#### StpUtil.getSessionByLoginId(Object loginId)
- 获取指定`loginId``session`(如果此id尚未创建`session`, 则返回`null`)
- 类似API还有
- `StpUtil.getSessionByLoginId(Object loginId, boolean isCreate)` 获取当前会话登录id, `isCreate`代表指定是否在无`session`的情况下新建并返回
#### StpUtil.hasPermission(Object login_id, Object pcode)
- 指定login_id是否含有指定权限
#### StpUtil.hasPermission(Object loginId, Object pcode)
- 指定`loginId`是否含有指定权限

View File

@@ -3,10 +3,10 @@
## 何为无cookie
- 常规PC端鉴权方法一般由cookie进行
- 而cookie有两个特性1、可由后端控制写入2、每次请求自动提交
- 常规PC端鉴权方法一般由`cookie`进行
-`cookie`有两个特性1、可由后端控制写入2、每次请求自动提交
- 这就使得大多数web前端码农无需任何特殊操作就能完成鉴权的流程因为整个流程都是后端控制完成的
- 而在app、小程序等前后台分离场景中是没有cookie这一功能的此时大多数人都会一脸懵逼咋进行鉴权啊
- 而在app、小程序等前后台分离场景中是没有`cookie`这一功能的,此时大多数人都会一脸懵逼,咋进行鉴权啊
- 其实很简单
- 不能后端控制写入了,就前端自己写入(难点在**如何将token传递到前端**
- 每次请求不能自动提交了,那就手动提交(难点在前端如何**将token传递到后端**,同时后端**将其读取出来**
@@ -14,14 +14,14 @@
## 将token传递到前端
1. 首先调用 `StpUtil.setLoginId(Object login_id)` 进行登录
1. 首先调用 `StpUtil.setLoginId(Object loginId)` 进行登录
2. 调用 `StpUtil.getTokenInfo()` 返回当前会话的token值
- 此方法返回一个Map有两个keytokenNametokenValuetoken的名称和token的值
- 此方法返回一个Map有两个key`tokenName``tokenValue``token`的名称和`token`的值)
- 将此Map传递到前台让前端人员将这两个值保存到本地
## 前端将token提交到后端
1. 无论是app还是小程序其传递方式都大同小异
2. 那就是将token塞到请求header里 ,格式为:`{tokenName: tokenValue}`
2. 那就是,将`token`塞到请求`header`里 ,格式为:`{tokenName: tokenValue}`
3. 以经典跨端框架`uni-app`为例:
**方式1简单粗暴**
@@ -71,13 +71,13 @@
});
```
4. 只要按照如此方法将token值传递到后端`sa-token`就能像传统PC端一样自动读取到token值进行鉴权
5. 你可能会有疑问难道我每个ajax都要写这么一坨岂不是麻烦死了
- 你当然不能每个ajax都写这么一坨因为这种重复代码都是要封装在一个函数里统一调用的
4. 只要按照如此方法将`token`值传递到后端,`sa-token`就能像传统PC端一样自动读取到`token`值,进行鉴权
5. 你可能会有疑问,难道我每个`ajax`都要写这么一坨?岂不是麻烦死了
- 你当然不能每个`ajax`都写这么一坨,因为这种重复代码都是要封装在一个函数里统一调用的
## 其它解决方案?
- 如果你对cookie非常了解那你就会明白所谓cookie本质上就是一个特殊的header参数而已
- 而既然它只是一个header参数我们就能就能手动模拟实现它从而完成鉴权操作
- 这其实是对无cookie模式的另一种解决方案有兴趣的同学可以百度了解一下在此暂不赘述
- 如果你对`cookie`非常了解,那你就会明白,所谓`cookie`,本质上就是一个特殊的`header`参数而已,
- 而既然它只是一个`header`参数,我们就能就能手动模拟实现它,从而完成鉴权操作
- 这其实是对无`cookie`模式的另一种解决方案,有兴趣的同学可以百度了解一下,在此暂不赘述

View File

@@ -3,35 +3,35 @@
## 账号session
账号session指的是为每个登录账号分配的session
账号`session`指的是为每个登录账号分配的`session`
#### StpUtil.getSession()
- 返回当前登录账号的session必须是登录后才能调用
- 返回当前登录账号的`session`(必须是登录后才能调用)
## 自定义session
自定义session指的是未登录状态下以一个特定的值作为key来分配的session
自定义`session`指的是未登录状态下以一个特定的值作为key来分配的`session`
#### SaSessionCustomUtil.isExists(String sessionId)
- 查询指定key的session是否存在
- 查询指定key的`session`,是否存在
#### SaSessionCustomUtil.getSessionById(String sessionId)
- 获取指定key的session如果没有则新建并返回
- 获取指定key的`session`,如果没有,则新建并返回
#### SaSessionCustomUtil.delSessionById(String sessionId)
- 删除指定key的session
- 删除指定key的`session`
## session相关操作
那么获取到的`SaSession`具体有哪些方法可供操作?
#### getId()
- 返回此session的id
- 返回此`session`的id
#### setAttribute(String key, Object value)
- 在此session对象上写入值
- 在此`session`对象上写入值
#### getAttribute(String key)
- 在此session对象上查询值
- 在此`session`对象上查询值
具体可参考`javax.servlet.http.HttpSession``SaSession`所含方法与其大体类似

View File

@@ -42,7 +42,7 @@
<!-- 内容部分 -->
<div class="main-box">
<div class="content-box">
<h1>sa-token<small>v1.0.3</small></h1>
<h1>sa-token<small>v1.4.0</small></h1>
<div class="sub-title">一个JavaWeb权限认证框架强大、简单、好用</div>
<!-- <p>0配置开箱即用低学习成本</p> -->
<p>登录验证、权限验证、自定义session会话、踢人下线、持久层扩展、无cookie模式、模拟他人账号、多账号体系、注解式鉴权、Spring集成...</p>
@@ -60,7 +60,7 @@
<p>
<span class="copyright">Copyright © 2020 &nbsp;</span>
<a href="http://www.miitbeian.gov.cn/" target="_blank">鲁ICP备18046274号-2</a> &nbsp;
QQ交流群<a href="https://jq.qq.com/?_wv=1027&k=5DHN5Ib" target="_blank">784013340</a>
QQ交流群<a href="https://jq.qq.com/?_wv=1027&k=5DHN5Ib" target="_blank">782974737</a>
</p>
</footer>