Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
shengzhang_
sa-token
提交
275b3cec
sa-token
项目概览
shengzhang_
/
sa-token
通知
68
Star
16
Fork
4
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
sa-token
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
275b3cec
编写于
3月 10, 2021
作者:
shengzhang_
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
完成 [记住我]模式 开发文档
上级
e92ff9fb
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
84 addition
and
25 deletion
+84
-25
sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java
...core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java
+26
-10
sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java
...ken-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java
+6
-6
sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java
...oken-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java
+3
-3
sa-token-demo-springboot/src/main/java/com/pj/test/GlobalException.java
...springboot/src/main/java/com/pj/test/GlobalException.java
+1
-2
sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java
...-springboot/src/main/java/com/pj/test/TestController.java
+3
-2
sa-token-doc/doc/use/remember-me.md
sa-token-doc/doc/use/remember-me.md
+45
-2
未找到文件。
sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java
浏览文件 @
275b3cec
...
...
@@ -2,6 +2,7 @@ package cn.dev33.satoken.stp;
import
cn.dev33.satoken.SaTokenManager
;
import
cn.dev33.satoken.config.SaTokenConfig
;
import
cn.dev33.satoken.dao.SaTokenDao
;
import
cn.dev33.satoken.util.SaTokenConsts
;
/**
...
...
@@ -23,9 +24,9 @@ public class SaLoginModel {
public
Long
timeout
;
/**
* 是否为
临时Cookie(临时Cookie会在浏览器关闭时自动删除
)
* 是否为
持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在
)
*/
public
Boolean
is
Temp
Cookie
;
public
Boolean
is
Lasting
Cookie
;
/**
...
...
@@ -61,21 +62,36 @@ public class SaLoginModel {
}
/**
* @return is
Temp
Cookie
* @return is
Lasting
Cookie
*/
public
Boolean
getIs
Temp
Cookie
()
{
return
is
Temp
Cookie
;
public
Boolean
getIs
Lasting
Cookie
()
{
return
is
Lasting
Cookie
;
}
/**
* @param is
TempCookie 要设置的 isTemp
Cookie
* @param is
LastingCookie 要设置的 isLasting
Cookie
* @return 对象自身
*/
public
SaLoginModel
setIs
TempCookie
(
Boolean
isTemp
Cookie
)
{
this
.
is
TempCookie
=
isTemp
Cookie
;
public
SaLoginModel
setIs
LastingCookie
(
Boolean
isLasting
Cookie
)
{
this
.
is
LastingCookie
=
isLasting
Cookie
;
return
this
;
}
/**
* @return cookie时长
*/
public
int
getCookieTimeout
()
{
if
(
isLastingCookie
==
false
)
{
return
-
1
;
}
if
(
timeout
==
SaTokenDao
.
NEVER_EXPIRE
)
{
return
Integer
.
MAX_VALUE
;
}
return
(
int
)(
long
)
timeout
;
}
/**
* 构建对象,初始化默认值
* @return 对象自身
...
...
@@ -96,8 +112,8 @@ public class SaLoginModel {
if
(
timeout
==
null
)
{
timeout
=
config
.
getTimeout
();
}
if
(
is
Temp
Cookie
==
null
)
{
is
TempCookie
=
fals
e
;
if
(
is
Lasting
Cookie
==
null
)
{
is
LastingCookie
=
tru
e
;
}
return
this
;
}
...
...
sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java
浏览文件 @
275b3cec
...
...
@@ -161,10 +161,10 @@ public class StpLogic {
/**
* 在当前会话上登录id, 并指定登录设备
* @param loginId 登录id,建议的类型:(long | int | String)
* @param is
TempCookie 是否为临时
Cookie
* @param is
LastingCookie 是否为持久
Cookie
*/
public
void
setLoginId
(
Object
loginId
,
boolean
is
Temp
Cookie
)
{
setLoginId
(
loginId
,
new
SaLoginModel
().
setIs
TempCookie
(
isTemp
Cookie
));
public
void
setLoginId
(
Object
loginId
,
boolean
is
Lasting
Cookie
)
{
setLoginId
(
loginId
,
new
SaLoginModel
().
setIs
LastingCookie
(
isLasting
Cookie
));
}
/**
...
...
@@ -234,9 +234,8 @@ public class StpLogic {
// 注入Cookie
if
(
config
.
getIsReadCookie
()
==
true
){
HttpServletResponse
response
=
SaTokenManager
.
getSaTokenServlet
().
getResponse
();
int
cookieTimeout
=
loginModel
.
getIsTempCookie
()
?
-
1
:
(
int
)(
long
)
loginModel
.
getTimeout
();
SaTokenManager
.
getSaTokenCookie
().
addCookie
(
response
,
getTokenName
(),
tokenValue
,
"/"
,
config
.
getCookieDomain
(),
cookieTimeout
);
"/"
,
config
.
getCookieDomain
(),
loginModel
.
getCookieTimeout
()
);
}
}
...
...
@@ -584,8 +583,9 @@ public class StpLogic {
setLastActivityToNow
(
tokenValue
);
// cookie注入
if
(
getConfig
().
getIsReadCookie
()
==
true
){
int
cookieTimeout
=
(
int
)(
getConfig
().
getTimeout
()
==
SaTokenDao
.
NEVER_EXPIRE
?
Integer
.
MAX_VALUE
:
getConfig
().
getTimeout
());
SaTokenManager
.
getSaTokenCookie
().
addCookie
(
SaTokenManager
.
getSaTokenServlet
().
getResponse
(),
getTokenName
(),
tokenValue
,
"/"
,
getConfig
().
getCookieDomain
(),
(
int
)
getConfig
().
getTimeout
()
);
"/"
,
getConfig
().
getCookieDomain
(),
cookieTimeout
);
}
}
}
...
...
sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java
浏览文件 @
275b3cec
...
...
@@ -75,10 +75,10 @@ public class StpUtil {
/**
* 在当前会话上登录id, 并指定登录设备
* @param loginId 登录id,建议的类型:(long | int | String)
* @param is
TempCookie 是否为临时
Cookie
* @param is
LastingCookie 是否为持久
Cookie
*/
public
void
setLoginId
(
Object
loginId
,
boolean
isTemp
Cookie
)
{
stpLogic
.
setLoginId
(
loginId
,
is
Temp
Cookie
);
public
static
void
setLoginId
(
Object
loginId
,
boolean
isLasting
Cookie
)
{
stpLogic
.
setLoginId
(
loginId
,
is
Lasting
Cookie
);
}
/**
...
...
sa-token-demo-springboot/src/main/java/com/pj/test/GlobalException.java
浏览文件 @
275b3cec
...
...
@@ -14,7 +14,6 @@ import com.pj.util.AjaxJson;
import
cn.dev33.satoken.exception.NotLoginException
;
import
cn.dev33.satoken.exception.NotPermissionException
;
import
cn.dev33.satoken.exception.NotRoleException
;
import
cn.dev33.satoken.stp.StpUtil
;
/**
* 全局异常处理
...
...
@@ -25,7 +24,7 @@ public class GlobalException {
// 在当前类每个方法进入之前触发的操作
@ModelAttribute
public
void
get
(
HttpServletRequest
request
)
throws
IOException
{
StpUtil
.
checkPermission
(
"user:add"
);
}
...
...
sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java
浏览文件 @
275b3cec
...
...
@@ -246,9 +246,10 @@ public class TestController {
// StpUtil.getTokenSession().logout();
// StpUtil.logoutByLoginId(10001);
// StpUtil.setLoginId(10001);
// StpUtil.setLoginId(10001,
new SaLoginModel().setIsTempCookie(true)
);
// StpUtil.setLoginId(10001,
false
);
// StpUtil.getLoginId();
// StpUtil.setLoginId(10001);
// StpUtil.getTokenSession();
return
AjaxJson
.
getSuccess
(
"访问成功"
);
}
...
...
sa-token-doc/doc/use/remember-me.md
浏览文件 @
275b3cec
...
...
@@ -10,9 +10,52 @@
### 在sa-token中实现记住我功能
sa-token的登录授权,
默认就是
`记住我`
模式,为了实现
`非记住我`
模式, 你需要做一些适配
sa-token的登录授权,
**默认就是`[记住我]`模式**
,为了实现
`[非记住我]`
模式, 你需要在登录时如下设置:
要
```
java
// 设置登录账号id为10001,第二个参数指定是否为[记住我],当此值为false后,关闭浏览器后再次打开需要重新登录
StpUtil
.
setLoginId
(
10001
,
false
);
```
那么,sa-token实现
`[记住我]`
的具体原理是?
### 实现原理
Cookie作为浏览器提供的默认会话跟踪机制,其生命周期有两种形式,分别是:
-
临时Cookie:有效期为本次会话,只要关闭浏览器窗口,Cookie就会消失
-
永久Cookie:有效期为一个具体的时间,在时间未到期之前,即使用户关闭了浏览器Cookie也不会消失
利用Cookie的此特性,我们便可以轻松实现 [记住我] 模式:
-
勾选[记住我]按钮时:调用
`StpUtil.setLoginId(10001, true)`
,在浏览器写入一个
`永久Cookie`
保存token,此时用户即使重启浏览器token依然有效
-
不勾选[记住我]按钮时:调用
`StpUtil.setLoginId(10001, false)`
,在浏览器写入一个
`临时Cookie`
保存token,此时用户在重启浏览器后token便会消失,导致会话失效
### 前后台分离模式下如何实现[记住我]?
此时机智的你😏很快发现一个问题,Cookie虽好,却无法在前后端分离环境下使用,那是不是代表上述方案在APP、小程序等环境中无效?
准确的讲,答案是肯定的,任何基于Cookie的认证方案在前后台分离环境下都会失效(原因在于这些客户端默认没有实现Cookie功能),不过好在,这些客户端一般都提供了替代方案,
唯一遗憾的是,此场景中token的生命周期需要我们在前端手动控制
以经典跨端框架
[
uni-app
](
https://uniapp.dcloud.io/
)
为例,我们可以使用如下方式达到同样的效果:
```
js
// 使用本地存储保存token,达到 [永久Cookie] 的效果
uni
.
setStorageSync
(
"
satoken
"
,
"
xxxx-xxxx-xxxx-xxxx-xxx
"
);
// 使用globalData保存token,达到 [临时Cookie] 的效果
getApp
().
globalData
.
satoken
=
"
xxxx-xxxx-xxxx-xxxx-xxx
"
;
```
如果你决定在PC浏览器环境下进行前后台分离模式开发,那么更加简单:
```
js
// 使用 localStorage 保存token,达到 [永久Cookie] 的效果
localStorage
.
setItem
(
"
satoken
"
,
"
xxxx-xxxx-xxxx-xxxx-xxx
"
);
// 使用 sessionStorage 保存token,达到 [临时Cookie] 的效果
sessionStorage
.
setItem
(
"
satoken
"
,
"
xxxx-xxxx-xxxx-xxxx-xxx
"
);
```
Remember me, it's too easy!
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录