From 69ce298a8aa99e4d66605800df47d88499d0726d Mon Sep 17 00:00:00 2001 From: shengzhang <2393584716@qq.com> Date: Thu, 18 Mar 2021 13:06:24 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8Dtoken=E5=89=8D=E7=BC=80?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev33/satoken/config/SaTokenConfig.java | 24 +++++++- .../java/cn/dev33/satoken/stp/StpLogic.java | 59 ++++++++++++------- .../main/java/com/pj/test/TestController.java | 1 + .../src/main/resources/application.yml | 1 + sa-token-doc/doc/use/many-account.md | 2 +- 5 files changed, 62 insertions(+), 25 deletions(-) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java index 34cce1e4..684fcf04 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java @@ -51,6 +51,9 @@ public class SaTokenConfig { /** 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景 */ private String cookieDomain; + + /** token前缀, 格式样例(satoken: Bearer xxxx-xxxx-xxxx-xxxx) */ + private String tokenPrefix; /** 是否在初始化配置时打印版本字符画 */ private Boolean isV = true; @@ -269,6 +272,22 @@ public class SaTokenConfig { return this; } + /** + * @return token前缀, 格式样例(satoken: Bearer xxxx-xxxx-xxxx-xxxx) + */ + public String getTokenPrefix() { + return tokenPrefix; + } + + /** + * @param tokenPrefix token前缀, 格式样例(satoken: Bearer xxxx-xxxx-xxxx-xxxx) + * @return 对象自身 + */ + public SaTokenConfig setTokenPrefix(String tokenPrefix) { + this.tokenPrefix = tokenPrefix; + return this; + } + /** * @return 是否在初始化配置时打印版本字符画 */ @@ -285,6 +304,7 @@ public class SaTokenConfig { return this; } + /** * toString @@ -295,8 +315,8 @@ public class SaTokenConfig { + ", allowConcurrentLogin=" + allowConcurrentLogin + ", isShare=" + isShare + ", isReadBody=" + isReadBody + ", isReadHead=" + isReadHead + ", isReadCookie=" + isReadCookie + ", tokenStyle=" + tokenStyle + ", dataRefreshPeriod=" + dataRefreshPeriod + ", tokenSessionCheckLogin=" - + tokenSessionCheckLogin + ", autoRenew=" + autoRenew + ", cookieDomain=" + cookieDomain + ", isV=" - + isV + "]"; + + tokenSessionCheckLogin + ", autoRenew=" + autoRenew + ", cookieDomain=" + cookieDomain + + ", tokenPrefix=" + tokenPrefix + ", isV=" + isV + "]"; } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java index d7486d30..60abb642 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java @@ -24,6 +24,7 @@ import cn.dev33.satoken.fun.SaFunction; import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.TokenSign; import cn.dev33.satoken.util.SaTokenConsts; +import cn.dev33.satoken.util.SaTokenInsideUtil; /** * sa-token 权限验证,逻辑实现类 @@ -84,6 +85,23 @@ public class StpLogic { return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey); } + /** + * 在当前会话写入当前tokenValue + * @param tokenValue token值 + */ + public void setTokenValue(String tokenValue, int cookieTimeout){ + // 将token保存到本次request里 + HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest(); + request.setAttribute(splicingKeyJustCreatedSave(), tokenValue); + // 注入Cookie + SaTokenConfig config = getConfig(); + if(config.getIsReadCookie() == true){ + HttpServletResponse response = SaTokenManager.getSaTokenServlet().getResponse(); + SaTokenManager.getSaTokenCookie().addCookie(response, getTokenName(), tokenValue, + "/", config.getCookieDomain(), cookieTimeout); + } + } + /** * 获取当前tokenValue * @return 当前tokenValue @@ -115,7 +133,16 @@ public class StpLogic { } } - // 5. 返回 + // 5. 如果打开了前缀模式 + String tokenPrefix = getConfig().getTokenPrefix(); + if(SaTokenInsideUtil.isEmpty(tokenPrefix) == false && SaTokenInsideUtil.isEmpty(tokenValue) == false) { + // 如果token以指定的前缀开头, 则裁剪掉它 + if(tokenValue.startsWith(tokenPrefix + " ")) { + tokenValue = tokenValue.substring(tokenPrefix.length() + 1); + } + } + + // 6. 返回 return tokenValue; } @@ -175,7 +202,6 @@ public class StpLogic { public void setLoginId(Object loginId, SaLoginModel loginModel) { // ------ 1、获取相应对象 - HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest(); SaTokenConfig config = getConfig(); SaTokenDao dao = SaTokenManager.getSaTokenDao(); loginModel.build(config); @@ -190,7 +216,7 @@ public class StpLogic { } } else { // --- 如果不允许并发登录 - // 如果此时[id-session]不为null,说明此账号在其他地正在登录,现在需要先把其它地的同设备token标记为被顶下线 + // 如果此时[user-session]不为null,说明此账号在其他地正在登录,现在需要先把其它地的同设备token标记为被顶下线 SaSession session = getSessionByLoginId(loginId, false); if(session != null) { List tokenSignList = session.getTokenSignList(); @@ -200,7 +226,7 @@ public class StpLogic { dao.update(splicingKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED); // 2. 清理掉[token-最后操作时间] clearLastActivity(tokenSign.getValue()); - // 3. 清理账号session上的token签名记录 + // 3. 清理user-session上的token签名记录 session.removeTokenSign(tokenSign.getValue()); } } @@ -227,16 +253,10 @@ public class StpLogic { // ------ 4. 持久化其它数据 // token -> uid dao.set(splicingKeyTokenValue(tokenValue), String.valueOf(loginId), loginModel.getTimeout()); - // 将token保存到本次request里 - request.setAttribute(splicingKeyJustCreatedSave(), tokenValue); // 写入 [最后操作时间] setLastActivityToNow(tokenValue); - // 注入Cookie - if(config.getIsReadCookie() == true){ - HttpServletResponse response = SaTokenManager.getSaTokenServlet().getResponse(); - SaTokenManager.getSaTokenCookie().addCookie(response, getTokenName(), tokenValue, - "/", config.getCookieDomain(), loginModel.getCookieTimeout()); - } + // 在当前会话写入当前tokenValue + setTokenValue(tokenValue, loginModel.getCookieTimeout()); } /** @@ -577,16 +597,11 @@ public class StpLogic { if(tokenValue == null || Objects.equals(tokenValue, "")) { // 随机一个token送给Ta tokenValue = createTokenValue(null); - // Request做上标记 - SaTokenManager.getSaTokenServlet().getRequest().setAttribute(splicingKeyJustCreatedSave(), tokenValue); // 写入 [最后操作时间] 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(), cookieTimeout); - } + // 在当前会话写入这个tokenValue + int cookieTimeout = (int)(getConfig().getTimeout() == SaTokenDao.NEVER_EXPIRE ? Integer.MAX_VALUE : getConfig().getTimeout()); + setTokenValue(tokenValue, cookieTimeout); } } // 返回这个token对应的专属session @@ -1092,7 +1107,7 @@ public class StpLogic { * @return key */ public String splicingKeySwitch() { - return SaTokenConsts.SWITCH_TO_SAVE_KEY + getLoginKey(); + return SaTokenConsts.SWITCH_TO_SAVE_KEY + loginKey; } /** @@ -1100,7 +1115,7 @@ public class StpLogic { * @return key */ public String splicingKeyJustCreatedSave() { - return SaTokenConsts.JUST_CREATED_SAVE_KEY + getLoginKey(); + return SaTokenConsts.JUST_CREATED_SAVE_KEY + loginKey; } diff --git a/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java b/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java index ce27d2b5..294a6a99 100644 --- a/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java +++ b/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java @@ -248,6 +248,7 @@ public class TestController { // .setIsLastingCookie(true) // 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在) // .setTimeout(60 * 60 * 24 * 7) // 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的timeout值) // ); + StpUtil.getTokenSession(); return AjaxJson.getSuccess("访问成功"); } diff --git a/sa-token-demo-springboot/src/main/resources/application.yml b/sa-token-demo-springboot/src/main/resources/application.yml index 0ee1952f..e02a9df0 100644 --- a/sa-token-demo-springboot/src/main/resources/application.yml +++ b/sa-token-demo-springboot/src/main/resources/application.yml @@ -19,6 +19,7 @@ spring: token-style: uuid + # redis配置 redis: # Redis数据库索引(默认为0) diff --git a/sa-token-doc/doc/use/many-account.md b/sa-token-doc/doc/use/many-account.md index cada9b0d..2103e34d 100644 --- a/sa-token-doc/doc/use/many-account.md +++ b/sa-token-doc/doc/use/many-account.md @@ -44,7 +44,7 @@ ``` java // 底层的 StpLogic 对象 public static StpLogic stpLogic = new StpLogic("user") { - // 重写 `getTokenName` 函数,返回一个与 `StpUtil` 不同的token名称, 防止冲突 + // 重写 `splicingKeyTokenName` 函数,返回一个与 `StpUtil` 不同的token名称, 防止冲突 @Override public String splicingKeyTokenName() { return super.splicingKeyTokenName()+"-user";