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 d137e1f9..ec6a42cc 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 @@ -79,7 +79,10 @@ public class SaTokenConfig implements Serializable { * Http Basic 认证的账号和密码 */ private String basic = ""; - + + /** 配置当前项目的网络访问地址 */ + private String currDomain; + /** * SSO单点登录配置对象 @@ -394,6 +397,22 @@ public class SaTokenConfig implements Serializable { this.basic = basic; return this; } + + /** + * @return 配置当前项目的网络访问地址 + */ + public String getCurrDomain() { + return currDomain; + } + + /** + * @param currDomain 配置当前项目的网络访问地址 + * @return 对象自身 + */ + public SaTokenConfig setCurrDomain(String currDomain) { + this.currDomain = currDomain; + return this; + } /** * @return SSO单点登录配置对象 @@ -418,7 +437,7 @@ public class SaTokenConfig implements Serializable { + ", dataRefreshPeriod=" + dataRefreshPeriod + ", tokenSessionCheckLogin=" + tokenSessionCheckLogin + ", autoRenew=" + autoRenew + ", cookieDomain=" + cookieDomain + ", tokenPrefix=" + tokenPrefix + ", isPrint=" + isPrint + ", isLog=" + isLog + ", jwtSecretKey=" + jwtSecretKey + ", idTokenTimeout=" - + idTokenTimeout + ", basic=" + basic + ", sso=" + sso + "]"; + + idTokenTimeout + ", basic=" + basic + ", currDomain=" + currDomain + ", sso=" + sso + "]"; } /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/context/model/SaRequest.java b/sa-token-core/src/main/java/cn/dev33/satoken/context/model/SaRequest.java index 1a0a5eea..25c8b9f8 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/context/model/SaRequest.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/context/model/SaRequest.java @@ -115,7 +115,7 @@ public interface SaRequest { } /** - * 返回当前请求的url,不带query参数,例:http://xxx.com/ + * 返回当前请求的url,不带query参数,例:http://xxx.com/test * @return see note */ public String getUrl(); diff --git a/sa-token-doc/doc/_sidebar.md b/sa-token-doc/doc/_sidebar.md index 940ceb5a..7ffdfc0f 100644 --- a/sa-token-doc/doc/_sidebar.md +++ b/sa-token-doc/doc/_sidebar.md @@ -75,6 +75,7 @@ - [Token有效期详解](/fun/token-timeout) - [Session模型详解](/fun/session-model) - [TokenInfo参数详解](/fun/token-info) + - [解决反向代理 uri 丢失的问题](/fun/curr-domain) - [框架源码所有技术栈](/fun/tech-stack) - [为Sa-Token贡献代码](/fun/git-pr) - [Sa-Token框架掌握度--在线考试](/fun/sa-token-test) diff --git a/sa-token-doc/doc/fun/curr-domain.md b/sa-token-doc/doc/fun/curr-domain.md new file mode 100644 index 00000000..6958a25e --- /dev/null +++ b/sa-token-doc/doc/fun/curr-domain.md @@ -0,0 +1,73 @@ +# 解决反向代理 uri 丢失的问题 + +--- + +使用 `request.getRequestURL()` 可获取当前程序所在外网的访问地址,在 Sa-Token 中,其 `SaHolder.getRequest().getUrl()` 也正是借助此API完成, +有很多模块都用到了这个能力,比如SSO单点登录。 + +我们可以使用如下代码测试此API +``` java +// 显示当前程序所在外网的都访问地址 +@RequestMapping("test") +public String test() { + return "您访问的是:" + SaHolder.getRequest().getUrl(); +} +``` + +从浏览器访问此接口,我们可以看到: + +![test-curr-domain.png](https://oss.dev33.cn/sa-token/doc/test-curr-domain.png 's-w-sh') + +此 API 在本地开发时一般可以正常工作,然后如果我们在部署时使用 Nginx 做了一层反向代理后,其最终结果可能会和我们预想的有一点偏差: + +![test-curr-domain-fxdl.png](https://oss.dev33.cn/sa-token/doc/test-curr-domain-fxdl.png 's-w-sh') + +不仅是 Nginx,所有包含路由转发的地方都有可能导致上述丢失 uri 的现象,解决方案也很简单,既然程序无法自动识别,我们改成手动获取即可,Sa-Token 提供两个方案: + + +### 方案一:Nginx转发时追加 header 参数 + +##### 1、首先在 Nginx 代理转发的地方增加参数 + +![nginx-add-header.png](https://oss.dev33.cn/sa-token/doc/nginx-add-header.png 's-w-sh') + +重点是这一句:`proxy_set_header Public-Network-URL http://$http_host$request_uri;` + +##### 2、在程序中新增类 `CustomSaTokenContextForSpring.java`,重写获取uri的逻辑 + +``` java +@Primary +@Component +public class CustomSaTokenContextForSpring extends SaTokenContextForSpring { + + @Override + public SaRequest getRequest() { + return new SaRequestForServlet(SpringMVCUtil.getRequest()) { + @Override + public String getUrl() { + if(request.getHeader("Public-Network-URL") != null) { + return request.getHeader("Public-Network-URL"); + } + return request.getRequestURL().toString(); + } + }; + } + +} +``` + +其它逻辑保持不变,框架即可正确获取 uri 地址 + +!> 注意:步骤一与步骤二需要同步存在,否则可能有前端假传 header 参数造成安全问题 + + +### 方案二:直接在yml中配置当前项目的网络访问地址 + +在 `application.yml` 中增加配置: +``` yml +sa-token: + # 配置当前项目的网络访问地址 + curr-domain: http://local.dev33.cn:8902/api +``` + +即可避免路由转发过程中丢失 uri 的问题 diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaRequestForReactor.java b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaRequestForReactor.java index 8733b324..1e5ad6aa 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaRequestForReactor.java +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaRequestForReactor.java @@ -6,9 +6,11 @@ import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilterChain; +import cn.dev33.satoken.SaManager; import cn.dev33.satoken.context.model.SaRequest; import cn.dev33.satoken.reactor.context.SaReactorHolder; import cn.dev33.satoken.reactor.context.SaReactorSyncHolder; +import cn.dev33.satoken.util.SaFoxUtil; /** * Request for Reactor @@ -20,7 +22,7 @@ public class SaRequestForReactor implements SaRequest { /** * 底层Request对象 */ - ServerHttpRequest request; + protected ServerHttpRequest request; /** * 实例化 @@ -75,10 +77,14 @@ public class SaRequestForReactor implements SaRequest { } /** - * 返回当前请求的url,例:http://xxx.com/?id=127 + * 返回当前请求的url,例:http://xxx.com/test * @return see note */ public String getUrl() { + String currDomain = SaManager.getConfig().getCurrDomain(); + if(SaFoxUtil.isEmpty(currDomain) == false) { + return currDomain + this.getRequestPath(); + } return request.getURI().toString(); } diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaResponseForReactor.java b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaResponseForReactor.java index a76b1479..7c4a3965 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaResponseForReactor.java +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaResponseForReactor.java @@ -20,7 +20,7 @@ public class SaResponseForReactor implements SaResponse { /** * 底层Response对象 */ - ServerHttpResponse response; + protected ServerHttpResponse response; /** * 实例化 diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaStorageForReactor.java b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaStorageForReactor.java index 266ded6b..852b8073 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaStorageForReactor.java +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/model/SaStorageForReactor.java @@ -14,7 +14,7 @@ public class SaStorageForReactor implements SaStorage { /** * 底层Request对象 */ - ServerWebExchange exchange; + protected ServerWebExchange exchange; /** * 实例化 diff --git a/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaRequestForServlet.java b/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaRequestForServlet.java index 84e43f8e..3598bd8a 100644 --- a/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaRequestForServlet.java +++ b/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaRequestForServlet.java @@ -10,6 +10,7 @@ import javax.servlet.http.HttpServletResponse; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.context.model.SaRequest; import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.util.SaFoxUtil; /** * Request for Servlet @@ -21,7 +22,7 @@ public class SaRequestForServlet implements SaRequest { /** * 底层Request对象 */ - HttpServletRequest request; + protected HttpServletRequest request; /** * 实例化 @@ -80,10 +81,14 @@ public class SaRequestForServlet implements SaRequest { } /** - * 返回当前请求的url,例:http://xxx.com/?id=127 + * 返回当前请求的url,例:http://xxx.com/test * @return see note */ public String getUrl() { + String currDomain = SaManager.getConfig().getCurrDomain(); + if(SaFoxUtil.isEmpty(currDomain) == false) { + return currDomain + this.getRequestPath(); + } return request.getRequestURL().toString(); } diff --git a/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaResponseForServlet.java b/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaResponseForServlet.java index 748e8e96..c77588bc 100644 --- a/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaResponseForServlet.java +++ b/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaResponseForServlet.java @@ -19,7 +19,7 @@ public class SaResponseForServlet implements SaResponse { /** * 底层Request对象 */ - HttpServletResponse response; + protected HttpServletResponse response; /** * 实例化 diff --git a/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaStorageForServlet.java b/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaStorageForServlet.java index b5f57b1e..f7d81491 100644 --- a/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaStorageForServlet.java +++ b/sa-token-starter/sa-token-servlet/src/main/java/cn/dev33/satoken/servlet/model/SaStorageForServlet.java @@ -14,7 +14,7 @@ public class SaStorageForServlet implements SaStorage { /** * 底层Request对象 */ - HttpServletRequest request; + protected HttpServletRequest request; /** * 实例化 diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaRequestForSolon.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaRequestForSolon.java index 76baf5e5..75cc1573 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaRequestForSolon.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaRequestForSolon.java @@ -2,7 +2,9 @@ package cn.dev33.satoken.solon.model; import org.noear.solon.core.handle.Context; +import cn.dev33.satoken.SaManager; import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.util.SaFoxUtil; /** * @author noear @@ -10,7 +12,7 @@ import cn.dev33.satoken.context.model.SaRequest; */ public class SaRequestForSolon implements SaRequest { - Context ctx; + protected Context ctx; public SaRequestForSolon(){ ctx = Context.current(); @@ -43,6 +45,10 @@ public class SaRequestForSolon implements SaRequest { @Override public String getUrl() { + String currDomain = SaManager.getConfig().getCurrDomain(); + if(SaFoxUtil.isEmpty(currDomain) == false) { + return currDomain + this.getRequestPath(); + } return ctx.url(); } diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaResponseForSolon.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaResponseForSolon.java index f7eaaab4..583a4db0 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaResponseForSolon.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaResponseForSolon.java @@ -11,7 +11,7 @@ import cn.dev33.satoken.context.model.SaResponse; */ public class SaResponseForSolon implements SaResponse { - Context ctx; + protected Context ctx; public SaResponseForSolon() { ctx = Context.current(); diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaStorageForSolon.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaStorageForSolon.java index 7fc04579..ee60ebe9 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaStorageForSolon.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/model/SaStorageForSolon.java @@ -9,7 +9,7 @@ import org.noear.solon.core.handle.Context; */ public class SaStorageForSolon implements SaStorage { - Context ctx; + protected Context ctx; public SaStorageForSolon() { ctx = Context.current();