diff --git a/README.md b/README.md
index 231af7e399965858d528d54ef1b39c4beca9e71c..bb1bfc243bf95e49679c19075e0ebf546c0ec800 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ Sa-Token 三方插件合集,希望本仓库可以最大程度汇集社区的
| sa-token-three-example-plugin | 孔明 | 为第三方插件开发时提供的示例工程 | 未发布 | [详情](sa-token-three-example-plugin/README.md) |
| sa-token-three-redis-jackson-add-prefix | RockMan | 为 Sa-Token 在 Redis 中的 key 添加上指定前缀 | 未发布 | [详情](sa-token-three-redis-jackson-add-prefix/README.md) |
| sa-token-three-custom-check-permission | RockMan | 自定义 Sa-Token 的鉴权逻辑,不再一次性返回整个权限码集合给框架判断,而是根据自定义验证规则返回 true 或 false 给框架 | 未发布 | [详情](sa-token-three-custom-check-permission/README.md) |
+| sa-token-three-token-prefix-compatible-cookie | 就剩一个桃 | 让 sa-token 在打开前缀模式时,Cookie 鉴权依然生效 | 未发布 | [详情](sa-token-three-token-prefix-compatible-cookie/README.md) |
#### 使用方式
diff --git a/pom.xml b/pom.xml
index ba016fd4d82d212250f9fd1fce6389a999fb1897..186446e50549ef883ac89242e04dc9db3a451836 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,6 +21,7 @@
sa-token-three-example-plugin
sa-token-three-redis-jackson-add-prefix
sa-token-three-custom-check-permission
+ sa-token-three-token-prefix-compatible-cookie
diff --git a/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/pom.xml b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..08c12bbca7fa76c91abad36c4ebe2e829d26489f
--- /dev/null
+++ b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/pom.xml
@@ -0,0 +1,46 @@
+
+ 4.0.0
+ cn.dev33
+ sa-token-three-token-prefix-compatible-cookie-demo
+ 0.0.1-SNAPSHOT
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.5.14
+
+
+
+
+
+ 1.35.0.RC
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ cn.dev33
+ sa-token-spring-boot-starter
+ ${sa-token.version}
+
+
+
+
+ cn.dev33
+ sa-token-three-token-prefix-compatible-cookie
+ ${sa-token.version}
+
+
+
+
+
\ No newline at end of file
diff --git a/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/java/com/pj/SaTokenDemoApplication.java b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/java/com/pj/SaTokenDemoApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..90edfb9f866c326f1a8540906bb23520891d2fe5
--- /dev/null
+++ b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/java/com/pj/SaTokenDemoApplication.java
@@ -0,0 +1,20 @@
+package com.pj;
+
+import cn.dev33.satoken.SaManager;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Sa-Token 整合 sa-token-three-token-prefix-compatible-cookie 示例:使 token-prefix 兼容 Cookie 鉴权模式
+ * @author yigetao
+ *
+ */
+@SpringBootApplication
+public class SaTokenDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SaTokenDemoApplication.class, args);
+ System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig());
+ }
+
+}
diff --git a/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/java/com/pj/current/GlobalException.java b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/java/com/pj/current/GlobalException.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd2c086d52137f362e5fcffa8e0332534898d817
--- /dev/null
+++ b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/java/com/pj/current/GlobalException.java
@@ -0,0 +1,20 @@
+package com.pj.current;
+
+import cn.dev33.satoken.util.SaResult;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+/**
+ * 全局异常处理
+ * @author yigetao
+ */
+@RestControllerAdvice
+public class GlobalException {
+
+ @ExceptionHandler
+ public SaResult handlerException(Exception e) {
+ e.printStackTrace();
+ return SaResult.error(e.getMessage());
+ }
+
+}
diff --git a/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/java/com/pj/test/LoginController.java b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/java/com/pj/test/LoginController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4ae01f5a208979f75261ade1ad42c593b742061
--- /dev/null
+++ b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/java/com/pj/test/LoginController.java
@@ -0,0 +1,50 @@
+package com.pj.test;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.util.SaResult;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 登录测试
+ * @author yigetao
+ */
+@RestController
+@RequestMapping("/acc/")
+public class LoginController {
+
+ // 测试登录 ---- http://localhost:8081/acc/doLogin?id=10001
+ @RequestMapping("doLogin")
+ public SaResult doLogin(@RequestParam(defaultValue = "10001") long id) {
+ StpUtil.login(id);
+ return SaResult.ok();
+ }
+
+ // 查询登录状态 ---- http://localhost:8081/acc/isLogin
+ @RequestMapping("isLogin")
+ public SaResult isLogin() {
+ return SaResult.ok("是否登录:" + StpUtil.isLogin());
+ }
+
+ // 校验登录状态 ---- http://localhost:8081/acc/checkLogin
+ @RequestMapping("checkLogin")
+ public SaResult checkLogin() {
+ StpUtil.checkLogin();
+ return SaResult.ok("校验登录成功");
+ }
+
+ // 查询 Token 信息 ---- http://localhost:8081/acc/tokenInfo
+ @RequestMapping("tokenInfo")
+ public SaResult tokenInfo() {
+ return SaResult.data(StpUtil.getTokenInfo());
+ }
+
+ // 测试注销 ---- http://localhost:8081/acc/logout
+ @RequestMapping("logout")
+ public SaResult logout() {
+ StpUtil.logout();
+ return SaResult.ok();
+ }
+
+}
diff --git a/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/resources/application.yml b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/resources/application.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c2efd384297eabf15c02a44a117dc9ede45be6c7
--- /dev/null
+++ b/sa-token-three-demo/sa-token-three-token-prefix-compatible-cookie-demo/src/main/resources/application.yml
@@ -0,0 +1,7 @@
+# 端口
+server:
+ port: 8081
+
+sa-token:
+ # 配置 token 前缀
+ token-prefix: Bearer
\ No newline at end of file
diff --git a/sa-token-three-token-prefix-compatible-cookie/README.md b/sa-token-three-token-prefix-compatible-cookie/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..09882440e8c62a5fbf22014dce44a945a011f32d
--- /dev/null
+++ b/sa-token-three-token-prefix-compatible-cookie/README.md
@@ -0,0 +1,23 @@
+## sa-token-three-token-prefix-compatible-cookie
+
+### 插件介绍
+众所周知 Sa-Token 在打开前缀模式后,是没法再继续使用 Cookie 模式鉴权的,本插件可以让 Sa-Token 在打开前缀模式时,Cookie 鉴权依然生效
+
+
+### 使用方式
+在项目已经引入的 Sa-Token 依赖的情况下,继续引入此插件:
+
+``` xml
+
+
+ cn.dev33
+ sa-token-three-token-prefix-compatible-cookie
+ ${sa-token.version}
+
+```
+
+然后就可以让 Sa-Token 在打开前缀模式时,Cookie 鉴权依然生效了
+
+
+### 联系方式
+使用时如遇问题,请在 sa-token-three-plugin 中提交 issue 咨询
\ No newline at end of file
diff --git a/sa-token-three-token-prefix-compatible-cookie/pom.xml b/sa-token-three-token-prefix-compatible-cookie/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..306ec6c8b9deb1341134210abc7c516d998af591
--- /dev/null
+++ b/sa-token-three-token-prefix-compatible-cookie/pom.xml
@@ -0,0 +1,22 @@
+
+
+
+ sa-token-three-plugin
+ cn.dev33
+ ${revision}
+ ../pom.xml
+
+ 4.0.0
+
+ sa-token-three-token-prefix-compatible-cookie
+
+
+
+
+ cn.dev33
+ sa-token-core
+
+
+
\ No newline at end of file
diff --git a/sa-token-three-token-prefix-compatible-cookie/src/main/java/cn/dev33/satoken/three/stp/StpLogicForTokenPrefixCompatibleCookie.java b/sa-token-three-token-prefix-compatible-cookie/src/main/java/cn/dev33/satoken/three/stp/StpLogicForTokenPrefixCompatibleCookie.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5fd66452e5aa4c55109b829e7639b51127d0484
--- /dev/null
+++ b/sa-token-three-token-prefix-compatible-cookie/src/main/java/cn/dev33/satoken/three/stp/StpLogicForTokenPrefixCompatibleCookie.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020-2099 sa-token.cc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.dev33.satoken.three.stp;
+
+import cn.dev33.satoken.config.SaTokenConfig;
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaRequest;
+import cn.dev33.satoken.context.model.SaStorage;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.util.SaFoxUtil;
+import cn.dev33.satoken.util.SaTokenConsts;
+
+/**
+ * 自定义 StpLogic 的实现类,并重写登录校验相关方法,使 token-prefix 兼容 Cookie 模式鉴权
+ *
+ * @author yigetao
+ * @since 1.35.0
+ */
+public class StpLogicForTokenPrefixCompatibleCookie extends StpLogic {
+
+ public StpLogicForTokenPrefixCompatibleCookie() {
+ super(StpUtil.TYPE);
+ }
+
+ public StpLogicForTokenPrefixCompatibleCookie(String loginType) {
+ super(loginType);
+ }
+
+
+ /**
+ * 重写实现:使 token-prefix 兼容 Cookie 模式
+ */
+ @Override
+ public String getTokenValueNotCut(){
+
+ // 获取相应对象
+ SaStorage storage = SaHolder.getStorage();
+ SaRequest request = SaHolder.getRequest();
+ SaTokenConfig config = getConfigOrGlobal();
+ String keyTokenName = getTokenName();
+ String tokenValue = null;
+
+ // 1. 先尝试从 Storage 存储器里读取
+ if(storage.get(splicingKeyJustCreatedSave()) != null) {
+ tokenValue = String.valueOf(storage.get(splicingKeyJustCreatedSave()));
+ }
+ // 2. 再尝试从 请求体 里面读取
+ if(tokenValue == null && config.getIsReadBody()){
+ tokenValue = request.getParam(keyTokenName);
+ }
+ // 3. 再尝试从 header 头里读取
+ if(tokenValue == null && config.getIsReadHeader()){
+ tokenValue = request.getHeader(keyTokenName);
+ }
+ // 4. 最后尝试从 cookie 里读取
+ if(tokenValue == null && config.getIsReadCookie()){
+ tokenValue = request.getCookieValue(keyTokenName);
+ String configTokenPrefix = config.getTokenPrefix();
+ if(SaFoxUtil.isNotEmpty(configTokenPrefix)) {
+ tokenValue = configTokenPrefix + SaTokenConsts.TOKEN_CONNECTOR_CHAT + tokenValue;
+ }
+ }
+
+ // 5. 至此,不管有没有读取到,都不再尝试了,直接返回
+ return tokenValue;
+ }
+
+
+}
diff --git a/sa-token-three-token-prefix-compatible-cookie/src/main/resources/META-INF/spring.factories b/sa-token-three-token-prefix-compatible-cookie/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000000000000000000000000000000000000..086c8f745a4fc6b1dfd2b481106a98446c5c8f76
--- /dev/null
+++ b/sa-token-three-token-prefix-compatible-cookie/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.three.stp.StpLogicForTokenPrefixCompatibleCookie
\ No newline at end of file
diff --git a/sa-token-three-token-prefix-compatible-cookie/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sa-token-three-token-prefix-compatible-cookie/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000000000000000000000000000000000000..db7ee16f3f89c06443c1ed963a87fcf90d3cbe22
--- /dev/null
+++ b/sa-token-three-token-prefix-compatible-cookie/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+cn.dev33.satoken.three.stp.StpLogicForTokenPrefixCompatibleCookie
\ No newline at end of file