diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaCookieConfig.java b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaCookieConfig.java index 1adf5fa0..269c04f8 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaCookieConfig.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaCookieConfig.java @@ -15,6 +15,9 @@ */ package cn.dev33.satoken.config; +import java.util.LinkedHashMap; +import java.util.Map; + /** * Sa-Token Cookie写入 相关配置 * @@ -54,6 +57,12 @@ public class SaCookieConfig { */ private String sameSite; + /** + * 额外扩展属性 + */ + private Map extraAttrs = new LinkedHashMap<>(); + + /** * 获取:Cookie 作用域 *

写入 Cookie 时显式指定的作用域, 常用于单点登录二级域名共享 Cookie 的场景。

@@ -140,11 +149,69 @@ public class SaCookieConfig { return this; } + /** + * @return 获取额外扩展属性 + */ + public Map getExtraAttrs() { + return extraAttrs; + } + + /** + * 写入额外扩展属性 + * @param extraAttrs / + * @return 对象自身 + */ + public SaCookieConfig setExtraAttrs(Map extraAttrs) { + this.extraAttrs = extraAttrs; + return this; + } + + /** + * 追加扩展属性 + * @param name / + * @param value / + * @return 对象自身 + */ + public SaCookieConfig addExtraAttr(String name, String value) { + if (extraAttrs == null) { + extraAttrs = new LinkedHashMap<>(); + } + this.extraAttrs.put(name, value); + return this; + } + + /** + * 追加扩展属性 + * @param name / + * @return 对象自身 + */ + public SaCookieConfig addExtraAttr(String name) { + return this.addExtraAttr(name, null); + } + + /** + * 移除指定扩展属性 + * @param name / + * @return 对象自身 + */ + public SaCookieConfig removeExtraAttr(String name) { + if(extraAttrs != null) { + this.extraAttrs.remove(name); + } + return this; + } + // toString @Override public String toString() { - return "SaCookieConfig [domain=" + domain + ", path=" + path + ", secure=" + secure + ", httpOnly=" + httpOnly - + ", sameSite=" + sameSite + "]"; + return "SaCookieConfig [" + + "domain=" + domain + + ", path=" + path + + ", secure=" + secure + + ", httpOnly=" + httpOnly + + ", sameSite=" + sameSite + + ", extraAttrs=" + extraAttrs + + "]"; } } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/context/model/SaCookie.java b/sa-token-core/src/main/java/cn/dev33/satoken/context/model/SaCookie.java index 7c944dca..8520773f 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/context/model/SaCookie.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/context/model/SaCookie.java @@ -15,14 +15,16 @@ */ package cn.dev33.satoken.context.model; +import cn.dev33.satoken.error.SaErrorCode; +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.util.SaFoxUtil; + import java.time.Instant; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; - -import cn.dev33.satoken.error.SaErrorCode; -import cn.dev33.satoken.exception.SaTokenException; -import cn.dev33.satoken.util.SaFoxUtil; +import java.util.LinkedHashMap; +import java.util.Map; /** * Cookie Model,代表一个 Cookie 应该具有的所有参数 @@ -77,6 +79,13 @@ public class SaCookie { */ private String sameSite; + // Cookie 属性参考文章:https://blog.csdn.net/fengbin2005/article/details/136544226 + + /** + * 额外扩展属性 + */ + private Map extraAttrs = new LinkedHashMap<>(); + /** * 构造一个 @@ -224,13 +233,73 @@ public class SaCookie { return this; } + /** + * @return 获取额外扩展属性 + */ + public Map getExtraAttrs() { + return extraAttrs; + } + + /** + * 写入额外扩展属性 + * @param extraAttrs / + * @return 对象自身 + */ + public SaCookie setExtraAttrs(Map extraAttrs) { + this.extraAttrs = extraAttrs; + return this; + } + + /** + * 追加扩展属性 + * @param name / + * @param value / + * @return 对象自身 + */ + public SaCookie addExtraAttr(String name, String value) { + if (extraAttrs == null) { + extraAttrs = new LinkedHashMap<>(); + } + this.extraAttrs.put(name, value); + return this; + } + + /** + * 追加扩展属性 + * @param name / + * @return 对象自身 + */ + public SaCookie addExtraAttr(String name) { + return this.addExtraAttr(name, null); + } + + /** + * 移除指定扩展属性 + * @param name / + * @return 对象自身 + */ + public SaCookie removeExtraAttr(String name) { + if(extraAttrs != null) { + this.extraAttrs.remove(name); + } + return this; + } + // toString @Override public String toString() { - return "SaCookie [name=" + name + ", value=" + value + ", maxAge=" + maxAge + ", domain=" + domain + ", path=" + path - + ", secure=" + secure + ", httpOnly=" + httpOnly + ", sameSite=" - + sameSite + "]"; + return "SaCookie [" + + "name=" + name + + ", value=" + value + + ", maxAge=" + maxAge + + ", domain=" + domain + + ", path=" + path + + ", secure=" + secure + + ", httpOnly=" + httpOnly + + ", sameSite=" + sameSite + + ", extraAttrs=" + extraAttrs + + "]"; } /** @@ -256,6 +325,7 @@ public class SaCookie { throw new SaTokenException("无效Value:" + value).setCode(SaErrorCode.CODE_12003); } + // example: // Set-Cookie: name=value; Max-Age=100000; Expires=Tue, 05-Oct-2021 20:28:17 GMT; Domain=localhost; Path=/; Secure; HttpOnly; SameSite=Lax StringBuilder sb = new StringBuilder(); @@ -287,6 +357,17 @@ public class SaCookie { sb.append("; SameSite=").append(sameSite); } + // 扩展属性 + if(extraAttrs != null) { + extraAttrs.forEach((k, v) -> { + if(SaFoxUtil.isEmpty(v)) { + sb.append("; ").append(k); + } else { + sb.append("; ").append(k).append("=").append(v); + } + }); + } + return sb.toString(); } 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 f2df96cb..ba8c1bd5 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 @@ -248,6 +248,7 @@ public class StpLogic { .setSecure(cfg.getSecure()) .setHttpOnly(cfg.getHttpOnly()) .setSameSite(cfg.getSameSite()) + .setExtraAttrs(cfg.getExtraAttrs()) ; SaHolder.getResponse().addCookie(cookie); }