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 2d6cf4e8..82efadd0 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 @@ -41,7 +41,7 @@ public class SaTokenConfig implements Serializable { private Boolean isReadBody = true; /** 是否尝试从header里读取token */ - private Boolean isReadHead = true; + private Boolean isReadHeader = true; /** 是否尝试从cookie里读取token */ private Boolean isReadCookie = true; @@ -211,16 +211,16 @@ public class SaTokenConfig implements Serializable { /** * @return 是否尝试从header里读取token */ - public Boolean getIsReadHead() { - return isReadHead; + public Boolean getIsReadHeader() { + return isReadHeader; } /** - * @param isReadHead 是否尝试从header里读取token + * @param isReadHeader 是否尝试从header里读取token * @return 对象自身 */ - public SaTokenConfig setIsReadHead(Boolean isReadHead) { - this.isReadHead = isReadHead; + public SaTokenConfig setIsReadHeader(Boolean isReadHeader) { + this.isReadHeader = isReadHeader; return this; } @@ -460,7 +460,7 @@ public class SaTokenConfig implements Serializable { + ", isShare=" + isShare + ", maxLoginCount=" + maxLoginCount + ", isReadBody=" + isReadBody - + ", isReadHead=" + isReadHead + + ", isReadHeader=" + isReadHeader + ", isReadCookie=" + isReadCookie + ", tokenStyle=" + tokenStyle + ", dataRefreshPeriod=" + dataRefreshPeriod @@ -480,44 +480,22 @@ public class SaTokenConfig implements Serializable { /** - *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 setIsConcurrent() ,使用方式保持不变

- * @param allowConcurrentLogin see note - * @return see note + *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 getIsReadHead() ,使用方式保持不变

+ * @return 是否尝试从header里读取token */ @Deprecated - public SaTokenConfig setAllowConcurrentLogin(Boolean allowConcurrentLogin) { - this.isConcurrent = allowConcurrentLogin; - return this; + public Boolean getIsReadHead() { + return isReadHeader; } /** - *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 setIsConcurrent() ,使用方式保持不变

- * @param isV see note - * @return see note - */ - @Deprecated - public SaTokenConfig setIsV(Boolean isV) { - this.isPrint = isV; - return this; - } - - /** - *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 getCookie().getDomain() ,使用方式保持不变

- * @return 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景 - */ - @Deprecated - public String getCookieDomain() { - return getCookie().getDomain(); - } - - /** - *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 getCookie().setDomain() ,使用方式保持不变

- * @param cookieDomain 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景 + *

本函数设计已过时,未来版本可能移除此函数,请及时更换为 setIsReadHead() ,使用方式保持不变

+ * @param isReadHeader 是否尝试从header里读取token * @return 对象自身 */ @Deprecated - public SaTokenConfig setCookieDomain(String cookieDomain) { - this.getCookie().setDomain(cookieDomain); + public SaTokenConfig setIsReadHead(Boolean isReadHead) { + this.isReadHeader = isReadHead; return this; } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfigFactory.java b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfigFactory.java index 542ca7f0..cc350d63 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfigFactory.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfigFactory.java @@ -28,7 +28,17 @@ public class SaTokenConfigFactory { * @return 一个SaTokenConfig对象 */ public static SaTokenConfig createConfig() { - Map map = readPropToMap(configPath); + return createConfig(configPath); + } + + /** + * 根据指定路径路径获取配置信息 + * + * @param path 配置文件路径 + * @return 一个SaTokenConfig对象 + */ + public static SaTokenConfig createConfig(String path) { + Map map = readPropToMap(path); if (map == null) { // throw new RuntimeException("找不到配置文件:" + configPath, null); } 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 32c357a5..db808d5e 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 @@ -209,7 +209,7 @@ public class StpLogic { tokenValue = request.getParam(keyTokenName); } // 3. 尝试从header里读取 - if(tokenValue == null && config.getIsReadHead()){ + if(tokenValue == null && config.getIsReadHeader()){ tokenValue = request.getHeader(keyTokenName); } // 4. 尝试从cookie里读取 diff --git a/sa-token-doc/doc/fun/issue-template.md b/sa-token-doc/doc/fun/issue-template.md index 93d4bf2b..c2f02dad 100644 --- a/sa-token-doc/doc/fun/issue-template.md +++ b/sa-token-doc/doc/fun/issue-template.md @@ -6,7 +6,7 @@ > 2. 问题已得到处理的 issue 请大家及时手动关闭,如果超过24小时没有追问,我们将默认提交者已找到解决方案,关闭issue。 > 3. 有时候 issue 提交之后,没有得到及时回复,大家可以加入QQ群@管理员寻求帮助。 > 4. 请大家新建 issue 时删除不必要的模板信息、精简语句、**做好代码排版**,对于不方便描述的业务场景,可参阅 [Sa-Token 名词解释](https://sa-token.dev33.cn/doc/index.html#/more/noun-intro) 方便组织语句,这样有助于减低大家的沟通成本。 - +> 5. **代码截图要带上行号!报错信息要把异常堆栈截全!页面截图要把地址栏带上!Ajax请求要把请求地址、请求头、请求参数都截全!** --- diff --git a/sa-token-doc/doc/more/common-questions.md b/sa-token-doc/doc/more/common-questions.md index 54434607..ce24eec3 100644 --- a/sa-token-doc/doc/more/common-questions.md +++ b/sa-token-doc/doc/more/common-questions.md @@ -43,7 +43,7 @@ **如果是:未能读取到有效Token** - 可能1:前端没有提交 Token(最好从前端f12控制台看看请求参数里有 token 吗)。 - 可能2:前端提交了 Token,但是参数名不对。默认参数名是 `satoken`,可通过配置文件 `sa-token.token-name: satoken` 来更改。 -- 可能3:前端提交了 Token,但是你配置了框架不读取,比如说你配置了 `is-read-head=false`(关闭header读取),此时你再从 header 里提交token,框架就无法读取到。 +- 可能3:前端提交了 Token,但是你配置了框架不读取,比如说你配置了 `is-read-header=false`(关闭header读取),此时你再从 header 里提交token,框架就无法读取到。 - 可能4:前端提交了 Token,但是 Token前缀 不对,可参考:[自定义 Token 前缀](/up/token-prefix) - 可能5:你使用了 Nginx 反向代理,而且配置了 自定义Token名称,而且自定义的名称还带有下划线(比如 shop_token),而且还是你的项目还是从 Header头提交Token的,此时 Nginx 默认会吞掉你的下划线参数,可参考:[nginx做转发时,带下划线的header参数丢失](https://blog.csdn.net/zfw_666666/article/details/124420828) @@ -53,7 +53,7 @@ - 可能3:在不集成 Redis 的情况下:颁发 token 后,项目重启了,导致 token 无效。 - 可能4:在集成 Redis 的情况下:颁发 token 后,Redis重启了,导致 token 无效。 - 可能5:你提交的 token 和框架读取到的 token 不一致: - - 可能5.1:比如说你配置了`is-read-head=false`(关闭header读取),然后你从header提交`token-A`,而框架从Cookie里读取`token-B`,导致鉴权不通过(框架读取顺序为`body->header->cookie`) + - 可能5.1:比如说你配置了`is-read-header=false`(关闭header读取),然后你从header提交`token-A`,而框架从Cookie里读取`token-B`,导致鉴权不通过(框架读取顺序为`body->header->cookie`) - 可能5.2:比如说你配置了`token-name=x-token`(自定义token名称),此时你从header提交:`satoken:token-A`(参数名没对上),然后框架从header里读取不到你提交的token,转而继续从Cookie读取到了`token-B`。 - 可能6:在集成 jwt 插件的情况下: - 如果使用的是 Simple 模式:情况和不集成jwt一样。 diff --git a/sa-token-doc/doc/use/config.md b/sa-token-doc/doc/use/config.md index 8b568a7a..9dde2519 100644 --- a/sa-token-doc/doc/use/config.md +++ b/sa-token-doc/doc/use/config.md @@ -84,7 +84,7 @@ PS:两者的区别在于:**`模式1会覆盖yml中的配置,模式2会与y | isShare | Boolean | true | 在多人登录同一账号时,是否共用一个token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) | | maxLoginCount | int | 12 | 同一账号最大登录数量,-1代表不限 (只有在 `isConcurrent=true`, `isShare=false` 时此配置才有效),[详解](/use/config?id=配置项详解:maxlogincount) | | isReadBody | Boolean | true | 是否尝试从 请求体 里读取 Token | -| isReadHead | Boolean | true | 是否尝试从 header 里读取 Token | +| isReadHeader | Boolean | true | 是否尝试从 header 里读取 Token | | isReadCookie | Boolean | true | 是否尝试从 cookie 里读取 Token,此值为 false 后,`StpUtil.login(id)` 登录时也不会再往前端注入Cookie | | tokenStyle | String | uuid | token风格, [参考:自定义Token风格](/up/token-style) | | dataRefreshPeriod | int | 30 | 默认数据持久组件实现类中,每次清理过期数据间隔的时间 (单位: 秒) ,默认值30秒,设置为-1代表不启动定时清理 | diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java new file mode 100644 index 00000000..facef8cf --- /dev/null +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java @@ -0,0 +1,125 @@ +package cn.dev33.satoken.core.config; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import cn.dev33.satoken.config.SaCookieConfig; +import cn.dev33.satoken.config.SaTokenConfig; +import cn.dev33.satoken.config.SaTokenConfigFactory; + +/** + * 配置类测试 + * + * @author kong + * @since: 2022-9-4 + */ +public class SaTokenConfigTest { + + // 基本 get set 测试 + @Test + public void testProp() { + SaTokenConfig config = new SaTokenConfig(); + + config.setTokenName("nav-token"); + Assertions.assertEquals(config.getTokenName(), "nav-token"); + + config.setTimeout(100204); + Assertions.assertEquals(config.getTimeout(), 100204); + + config.setActivityTimeout(1804); + Assertions.assertEquals(config.getActivityTimeout(), 1804); + + config.setIsConcurrent(false); + Assertions.assertEquals(config.getIsConcurrent(), false); + + config.setIsShare(false); + Assertions.assertEquals(config.getIsShare(), false); + + config.setMaxLoginCount(11); + Assertions.assertEquals(config.getMaxLoginCount(), 11); + + config.setIsReadBody(false); + Assertions.assertEquals(config.getIsReadBody(), false); + + config.setIsReadHeader(false); + Assertions.assertEquals(config.getIsReadHeader(), false); + + config.setIsReadCookie(false); + Assertions.assertEquals(config.getIsReadCookie(), false); + + config.setTokenStyle("tik"); + Assertions.assertEquals(config.getTokenStyle(), "tik"); + + config.setDataRefreshPeriod(111); + Assertions.assertEquals(config.getDataRefreshPeriod(), 111); + + config.setTokenSessionCheckLogin(false); + Assertions.assertEquals(config.getTokenSessionCheckLogin(), false); + + config.setAutoRenew(false); + Assertions.assertEquals(config.getAutoRenew(), false); + + config.setTokenPrefix("token"); + Assertions.assertEquals(config.getTokenPrefix(), "token"); + + config.setIsPrint(false); + Assertions.assertEquals(config.getIsPrint(), false); + + config.setIsLog(false); + Assertions.assertEquals(config.getIsLog(), false); + + config.setJwtSecretKey("NgdfaXasARggr"); + Assertions.assertEquals(config.getJwtSecretKey(), "NgdfaXasARggr"); + + config.setIdTokenTimeout(1004); + Assertions.assertEquals(config.getIdTokenTimeout(), 1004); + + config.setBasic("sa:123456"); + Assertions.assertEquals(config.getBasic(), "sa:123456"); + + config.setCurrDomain("http://127.0.0.1:8084"); + Assertions.assertEquals(config.getCurrDomain(), "http://127.0.0.1:8084"); + + config.setCheckIdToken(false); + Assertions.assertEquals(config.getCheckIdToken(), false); + + SaCookieConfig scc = new SaCookieConfig(); + config.setCookie(scc); + Assertions.assertEquals(config.getCookie(), scc); + } + + // 从文件读取 + @Test + public void testSaTokenConfigFactory() { + SaTokenConfig config = SaTokenConfigFactory.createConfig("sa-token2.properties"); + Assertions.assertEquals(config.getTokenName(), "use-token"); + Assertions.assertEquals(config.getTimeout(), 9000); + Assertions.assertEquals(config.getActivityTimeout(), 240); + Assertions.assertEquals(config.getIsConcurrent(), false); + Assertions.assertEquals(config.getIsShare(), false); + Assertions.assertEquals(config.getIsLog(), true); + } + + // 测试 SaCookieConfig + @Test + public void testSaCookieConfig() { + SaCookieConfig config = new SaCookieConfig(); + + config.setDomain("stp.cn"); + Assertions.assertEquals(config.getDomain(), "stp.cn"); + + config.setPath("/pro/"); + Assertions.assertEquals(config.getPath(), "/pro/"); + + config.setSecure(true); + Assertions.assertEquals(config.getSecure(), true); + + config.setHttpOnly(false); + Assertions.assertEquals(config.getHttpOnly(), false); + + config.setSameSite("lax"); + Assertions.assertEquals(config.getSameSite(), "lax"); + + } + +} diff --git a/sa-token-test/sa-token-springboot-test/src/test/resources/application.yml b/sa-token-test/sa-token-springboot-test/src/test/resources/application.yml new file mode 100644 index 00000000..3b419c10 --- /dev/null +++ b/sa-token-test/sa-token-springboot-test/src/test/resources/application.yml @@ -0,0 +1,10 @@ +# 端口 +server: + port: 8081 + +# Sa-Token配置 +sa-token: + # Token名称 (同时也是cookie名称) + token-name: satoken + + \ No newline at end of file diff --git a/sa-token-test/sa-token-springboot-test/src/test/resources/sa-token2.properties b/sa-token-test/sa-token-springboot-test/src/test/resources/sa-token2.properties new file mode 100644 index 00000000..929ff96e --- /dev/null +++ b/sa-token-test/sa-token-springboot-test/src/test/resources/sa-token2.properties @@ -0,0 +1,12 @@ +# token名称 (同时也是cookie名称) +tokenName=use-token +# token有效期,单位s 默认30天, -1代表永不过期 +timeout=9000 +# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 +activityTimeout=240 +# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) =-1 +isConcurrent=false +# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) +isShare=false +# token风格 +isLog=true