提交 f7cf0153 编写于 作者: shengzhang_'s avatar shengzhang_

新增`SaLoginModel`登录参数Model,适配[记住我]模式 **[重要]**

上级 4965149c
......@@ -66,9 +66,11 @@ public class SaTokenConfig {
/**
* @param tokenName token名称 (同时也是cookie名称)
* @return 对象自身
*/
public void setTokenName(String tokenName) {
public SaTokenConfig setTokenName(String tokenName) {
this.tokenName = tokenName;
return this;
}
/**
......@@ -80,9 +82,11 @@ public class SaTokenConfig {
/**
* @param timeout token的长久有效期(单位:秒) 默认30天, -1代表永久
* @return 对象自身
*/
public void setTimeout(long timeout) {
public SaTokenConfig setTimeout(long timeout) {
this.timeout = timeout;
return this;
}
/**
......@@ -96,9 +100,11 @@ public class SaTokenConfig {
/**
* @param activityTimeout token临时有效期 [指定时间内无操作就视为token过期] (单位: 秒), 默认-1 代表不限制
* (例如可以设置为1800代表30分钟内无操作就过期)
* @return 对象自身
*/
public void setActivityTimeout(long activityTimeout) {
public SaTokenConfig setActivityTimeout(long activityTimeout) {
this.activityTimeout = activityTimeout;
return this;
}
/**
......@@ -110,9 +116,11 @@ public class SaTokenConfig {
/**
* @param allowConcurrentLogin 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
* @return 对象自身
*/
public void setAllowConcurrentLogin(Boolean allowConcurrentLogin) {
public SaTokenConfig setAllowConcurrentLogin(Boolean allowConcurrentLogin) {
this.allowConcurrentLogin = allowConcurrentLogin;
return this;
}
/**
......@@ -124,9 +132,11 @@ public class SaTokenConfig {
/**
* @param isShare 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
* @return 对象自身
*/
public void setIsShare(Boolean isShare) {
public SaTokenConfig setIsShare(Boolean isShare) {
this.isShare = isShare;
return this;
}
/**
......@@ -138,9 +148,11 @@ public class SaTokenConfig {
/**
* @param isReadBody 是否尝试从请求体里读取token
* @return 对象自身
*/
public void setIsReadBody(Boolean isReadBody) {
public SaTokenConfig setIsReadBody(Boolean isReadBody) {
this.isReadBody = isReadBody;
return this;
}
/**
......@@ -152,9 +164,11 @@ public class SaTokenConfig {
/**
* @param isReadHead 是否尝试从header里读取token
* @return 对象自身
*/
public void setIsReadHead(Boolean isReadHead) {
public SaTokenConfig setIsReadHead(Boolean isReadHead) {
this.isReadHead = isReadHead;
return this;
}
/**
......@@ -166,9 +180,11 @@ public class SaTokenConfig {
/**
* @param isReadCookie 是否尝试从cookie里读取token
* @return 对象自身
*/
public void setIsReadCookie(Boolean isReadCookie) {
public SaTokenConfig setIsReadCookie(Boolean isReadCookie) {
this.isReadCookie = isReadCookie;
return this;
}
/**
......@@ -180,9 +196,11 @@ public class SaTokenConfig {
/**
* @param tokenStyle token风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
* @return 对象自身
*/
public void setTokenStyle(String tokenStyle) {
public SaTokenConfig setTokenStyle(String tokenStyle) {
this.tokenStyle = tokenStyle;
return this;
}
/**
......@@ -195,9 +213,11 @@ public class SaTokenConfig {
/**
* @param dataRefreshPeriod 默认dao层实现类中,每次清理过期数据间隔的时间 (单位: 秒)
* ,默认值30秒,设置为-1代表不启动定时清理
* @return 对象自身
*/
public void setDataRefreshPeriod(int dataRefreshPeriod) {
public SaTokenConfig setDataRefreshPeriod(int dataRefreshPeriod) {
this.dataRefreshPeriod = dataRefreshPeriod;
return this;
}
/**
......@@ -210,9 +230,11 @@ public class SaTokenConfig {
/**
* @param tokenSessionCheckLogin 获取[token专属session]时是否必须登录
* (如果配置为true,会在每次获取[token-session]时校验是否登录)
* @return 对象自身
*/
public void setTokenSessionCheckLogin(Boolean tokenSessionCheckLogin) {
public SaTokenConfig setTokenSessionCheckLogin(Boolean tokenSessionCheckLogin) {
this.tokenSessionCheckLogin = tokenSessionCheckLogin;
return this;
}
/**
......@@ -224,9 +246,11 @@ public class SaTokenConfig {
/**
* @param autoRenew 是否打开自动续签 (如果此值为true, 框架会在每次直接或间接调用getLoginId()时进行一次过期检查与续签操作)
* @return 对象自身
*/
public void setAutoRenew(Boolean autoRenew) {
public SaTokenConfig setAutoRenew(Boolean autoRenew) {
this.autoRenew = autoRenew;
return this;
}
/**
......@@ -238,9 +262,11 @@ public class SaTokenConfig {
/**
* @param cookieDomain 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景
* @return 对象自身
*/
public void setCookieDomain(String cookieDomain) {
public SaTokenConfig setCookieDomain(String cookieDomain) {
this.cookieDomain = cookieDomain;
return this;
}
/**
......@@ -252,9 +278,11 @@ public class SaTokenConfig {
/**
* @param isV 是否在初始化配置时打印版本字符画
* @return 对象自身
*/
public void setIsV(Boolean isV) {
public SaTokenConfig setIsV(Boolean isV) {
this.isV = isV;
return this;
}
......
package cn.dev33.satoken.stp;
import cn.dev33.satoken.SaTokenManager;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.util.SaTokenConsts;
/**
* 调用StpUtil.setLogin()时的配置 Model
* @author kong
*
*/
public class SaLoginModel {
/**
* 此次登录的客户端设备标识
*/
public String device;
/**
* 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的timeout值)
*/
public Long timeout;
/**
* 是否为临时Cookie(临时Cookie会在浏览器关闭时自动删除)
*/
public Boolean isTempCookie;
/**
* @return device
*/
public String getDevice() {
return device;
}
/**
* @param device 要设置的 device
* @return 对象自身
*/
public SaLoginModel setDevice(String device) {
this.device = device;
return this;
}
/**
* @return timeout
*/
public Long getTimeout() {
return timeout;
}
/**
* @param timeout 要设置的 timeout
* @return 对象自身
*/
public SaLoginModel setTimeout(long timeout) {
this.timeout = timeout;
return this;
}
/**
* @return isTempCookie
*/
public Boolean getIsTempCookie() {
return isTempCookie;
}
/**
* @param isTempCookie 要设置的 isTempCookie
* @return 对象自身
*/
public SaLoginModel setIsTempCookie(Boolean isTempCookie) {
this.isTempCookie = isTempCookie;
return this;
}
/**
* 构建对象,初始化默认值
* @return 对象自身
*/
public SaLoginModel build() {
return build(SaTokenManager.getConfig());
}
/**
* 构建对象,初始化默认值
* @param config 配置对象
* @return 对象自身
*/
public SaLoginModel build(SaTokenConfig config) {
if(device == null) {
device = SaTokenConsts.DEFAULT_LOGIN_DEVICE;
}
if(timeout == null) {
timeout = config.getTimeout();
}
if(isTempCookie == null) {
isTempCookie = false;
}
return this;
}
/**
* 静态方法获取一个 SaLoginModel 对象
* @return SaLoginModel 对象
*/
public static SaLoginModel create() {
return new SaLoginModel();
}
}
......@@ -8,6 +8,7 @@ import java.util.Objects;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.dev33.satoken.SaTokenManager;
import cn.dev33.satoken.annotation.SaCheckLogin;
......@@ -145,20 +146,39 @@ public class StpLogic {
* @param loginId 登录id,建议的类型:(long | int | String)
*/
public void setLoginId(Object loginId) {
setLoginId(loginId, SaTokenConsts.DEFAULT_LOGIN_DEVICE);
setLoginId(loginId, new SaLoginModel());
}
/**
* 在当前会话上登录id
* 在当前会话上登录id, 并指定登录设备
* @param loginId 登录id,建议的类型:(long | int | String)
* @param device 设备标识
*/
public void setLoginId(Object loginId, String device) {
setLoginId(loginId, new SaLoginModel().setDevice(device));
}
/**
* 在当前会话上登录id, 并指定登录设备
* @param loginId 登录id,建议的类型:(long | int | String)
* @param isTempCookie 是否为临时Cookie
*/
public void setLoginId(Object loginId, boolean isTempCookie) {
setLoginId(loginId, new SaLoginModel().setIsTempCookie(isTempCookie));
}
/**
* 在当前会话上登录id, 并指定所有登录参数Model
* @param loginId 登录id,建议的类型:(long | int | String)
* @param loginModel 此次登录的参数Model
*/
public void setLoginId(Object loginId, SaLoginModel loginModel) {
// ------ 1、获取相应对象
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
SaTokenConfig config = getConfig();
SaTokenDao dao = SaTokenManager.getSaTokenDao();
loginModel.build(config);
// ------ 2、生成一个token
String tokenValue = null;
......@@ -166,7 +186,7 @@ public class StpLogic {
if(config.getAllowConcurrentLogin() == true) {
// 如果配置为共享token, 则尝试从Session签名记录里取出token
if(config.getIsShare() == true) {
tokenValue = getTokenValueByLoginId(loginId, device);
tokenValue = getTokenValueByLoginId(loginId, loginModel.getDevice());
}
} else {
// --- 如果不允许并发登录
......@@ -175,7 +195,7 @@ public class StpLogic {
if(session != null) {
List<TokenSign> tokenSignList = session.getTokenSignList();
for (TokenSign tokenSign : tokenSignList) {
if(tokenSign.getDevice().equals(device)) {
if(tokenSign.getDevice().equals(loginModel.getDevice())) {
// 1. 将此token 标记为已顶替
dao.update(getKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED);
// 2. 清理掉[token-最后操作时间]
......@@ -196,22 +216,27 @@ public class StpLogic {
if(session == null) {
session = getSessionByLoginId(loginId);
} else {
dao.updateSessionTimeout(session.getId(), config.getTimeout());
// 保证此Session的有效期 >= token的有效期
if(dao.getSessionTimeout(session.getId()) < loginModel.getTimeout()) {
dao.updateSessionTimeout(session.getId(), loginModel.getTimeout());
}
}
// 在session上记录token签名
session.addTokenSign(new TokenSign(tokenValue, device));
session.addTokenSign(new TokenSign(tokenValue, loginModel.getDevice()));
// ------ 4. 持久化其它数据
// token -> uid
dao.set(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout());
dao.set(getKeyTokenValue(tokenValue), String.valueOf(loginId), loginModel.getTimeout());
// 将token保存到本次request里
request.setAttribute(getKeyJustCreatedSave(), tokenValue);
// 写入 [最后操作时间]
setLastActivityToNow(tokenValue);
// cookie注入
if(config.getIsReadCookie() == true){
SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue,
"/", config.getCookieDomain(), (int)config.getTimeout());
// 注入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);
}
}
......
......@@ -64,13 +64,31 @@ public class StpUtil {
}
/**
* 在当前会话上登录id
* 在当前会话上登录id, 并指定登录设备
* @param loginId 登录id,建议的类型:(long | int | String)
* @param device 设备标识
*/
public static void setLoginId(Object loginId, String device) {
stpLogic.setLoginId(loginId, device);
}
/**
* 在当前会话上登录id, 并指定登录设备
* @param loginId 登录id,建议的类型:(long | int | String)
* @param isTempCookie 是否为临时Cookie
*/
public void setLoginId(Object loginId, boolean isTempCookie) {
stpLogic.setLoginId(loginId, isTempCookie);
}
/**
* 在当前会话上登录id, 并指定所有登录参数Model
* @param loginId 登录id,建议的类型:(long | int | String)
* @param loginModel 此次登录的参数Model
*/
public static void setLoginId(Object loginId, SaLoginModel loginModel) {
stpLogic.setLoginId(loginId, loginModel);
}
/**
* 当前会话注销登录
......
......@@ -3,6 +3,8 @@ package com.pj.test;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
......@@ -18,6 +20,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
......@@ -244,10 +247,13 @@ public class TestController {
// 测试 浏览器访问: http://localhost:8081/test/test
@RequestMapping("test")
public AjaxJson test() {
public AjaxJson test(HttpServletResponse response) {
// StpUtil.getTokenSession().logout();
// StpUtil.logoutByLoginId(10001);
// StpUtil.setLoginId(10001);
StpUtil.setLoginId(10001, new SaLoginModel().setIsTempCookie(true));
StpUtil.getLoginId();
return AjaxJson.getSuccess();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册