mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-05-02 20:02:45 +08:00
增加Cookie模式的secure、httpOnly、sameSite等配置
This commit is contained in:
parent
cf6632df79
commit
643118177a
@ -0,0 +1,122 @@
|
||||
package cn.dev33.satoken.config;
|
||||
|
||||
/**
|
||||
* Sa-Token Cookie写入 相关配置
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaCookieConfig {
|
||||
|
||||
/**
|
||||
* 域(写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景)
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 路径
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 是否只在 https 协议下有效
|
||||
*/
|
||||
private Boolean secure = false;
|
||||
|
||||
/**
|
||||
* 是否禁止 js 操作 Cookie
|
||||
*/
|
||||
private Boolean httpOnly = false;
|
||||
|
||||
/**
|
||||
* 第三方限制级别(Strict=完全禁止,Lax=部分允许,None=不限制)
|
||||
*/
|
||||
private String sameSite;
|
||||
|
||||
/**
|
||||
* @return 域 (写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景)
|
||||
*/
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param domain 域 (写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景)
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookieConfig setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 路径
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path 路径
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookieConfig setPath(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 是否只在 https 协议下有效
|
||||
*/
|
||||
public Boolean getSecure() {
|
||||
return secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param secure 是否只在 https 协议下有效
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookieConfig setSecure(Boolean secure) {
|
||||
this.secure = secure;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 是否禁止 js 操作 Cookie
|
||||
*/
|
||||
public Boolean getHttpOnly() {
|
||||
return httpOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param httpOnly 是否禁止 js 操作 Cookie
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookieConfig setHttpOnly(Boolean httpOnly) {
|
||||
this.httpOnly = httpOnly;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 第三方限制级别(Strict=完全禁止,Lax=部分允许,None=不限制)
|
||||
*/
|
||||
public String getSameSite() {
|
||||
return sameSite;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sameSite 第三方限制级别(Strict=完全禁止,Lax=部分允许,None=不限制)
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookieConfig setSameSite(String sameSite) {
|
||||
this.sameSite = sameSite;
|
||||
return this;
|
||||
}
|
||||
|
||||
// toString
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SaCookieConfig [domain=" + domain + ", path=" + path + ", secure=" + secure + ", httpOnly=" + httpOnly
|
||||
+ ", sameSite=" + sameSite + "]";
|
||||
}
|
||||
|
||||
}
|
@ -41,12 +41,6 @@ public class SaTokenConfig implements Serializable {
|
||||
/** 是否尝试从cookie里读取token */
|
||||
private Boolean isReadCookie = true;
|
||||
|
||||
/** 使用Cookie时,是否为HttpOnly */
|
||||
private Boolean isCookieHttpOnly = false;
|
||||
|
||||
/** 使用Cookie时,是否为Secure */
|
||||
private Boolean isCookieSecure = false;
|
||||
|
||||
/** token风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) */
|
||||
private String tokenStyle = "uuid";
|
||||
|
||||
@ -59,9 +53,6 @@ public class SaTokenConfig implements Serializable {
|
||||
/** 是否打开自动续签 (如果此值为true, 框架会在每次直接或间接调用getLoginId()时进行一次过期检查与续签操作) */
|
||||
private Boolean autoRenew = true;
|
||||
|
||||
/** 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景 */
|
||||
private String cookieDomain;
|
||||
|
||||
/** token前缀, 格式样例(satoken: Bearer xxxx-xxxx-xxxx-xxxx) */
|
||||
private String tokenPrefix;
|
||||
|
||||
@ -90,6 +81,11 @@ public class SaTokenConfig implements Serializable {
|
||||
private String currDomain;
|
||||
|
||||
|
||||
/**
|
||||
* Cookie配置对象
|
||||
*/
|
||||
public SaCookieConfig cookie = new SaCookieConfig();
|
||||
|
||||
/**
|
||||
* SSO单点登录配置对象
|
||||
*/
|
||||
@ -226,38 +222,6 @@ public class SaTokenConfig implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 使用Cookie时,是否为HttpOnly
|
||||
*/
|
||||
public Boolean getIsCookieHttpOnly() {
|
||||
return isCookieHttpOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isCookieHttpOnly 使用Cookie时,是否为HttpOnly
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenConfig setIsCookieHttpOnly(Boolean isCookieHttpOnly) {
|
||||
this.isCookieHttpOnly = isCookieHttpOnly;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 使用Cookie时,是否为Secure
|
||||
*/
|
||||
public Boolean getIsCookieSecure() {
|
||||
return isCookieSecure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isCookieSecure 使用Cookie时,是否为Secure
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenConfig setIsCookieSecure(Boolean isCookieSecure) {
|
||||
this.isCookieSecure = isCookieSecure;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return token风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
|
||||
*/
|
||||
@ -324,22 +288,6 @@ public class SaTokenConfig implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景
|
||||
*/
|
||||
public String getCookieDomain() {
|
||||
return cookieDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cookieDomain 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenConfig setCookieDomain(String cookieDomain) {
|
||||
this.cookieDomain = cookieDomain;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return token前缀, 格式样例(satoken: Bearer xxxx-xxxx-xxxx-xxxx)
|
||||
*/
|
||||
@ -461,23 +409,54 @@ public class SaTokenConfig implements Serializable {
|
||||
|
||||
/**
|
||||
* @param sso SSO单点登录配置对象
|
||||
* @return 对象自身
|
||||
*/
|
||||
public void setSso(SaSsoConfig sso) {
|
||||
public SaTokenConfig setSso(SaSsoConfig sso) {
|
||||
this.sso = sso;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Cookie 全局配置对象
|
||||
*/
|
||||
public SaCookieConfig getCookie() {
|
||||
return cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cookie Cookie 全局配置对象
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenConfig setCookie(SaCookieConfig cookie) {
|
||||
this.cookie = cookie;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SaTokenConfig [tokenName=" + tokenName + ", timeout=" + timeout + ", activityTimeout=" + activityTimeout
|
||||
+ ", isConcurrent=" + isConcurrent + ", isShare=" + isShare + ", isReadBody=" + isReadBody
|
||||
+ ", isReadHead=" + isReadHead + ", isReadCookie=" + isReadCookie
|
||||
+ ", isCookieHttpOnly=" + isCookieHttpOnly + ", isCookieSecure=" + isCookieSecure
|
||||
return "SaTokenConfig ["
|
||||
+ "tokenName=" + tokenName
|
||||
+ ", timeout=" + timeout
|
||||
+ ", activityTimeout=" + activityTimeout
|
||||
+ ", isConcurrent=" + isConcurrent
|
||||
+ ", isShare=" + isShare
|
||||
+ ", isReadBody=" + isReadBody
|
||||
+ ", isReadHead=" + isReadHead
|
||||
+ ", isReadCookie=" + isReadCookie
|
||||
+ ", tokenStyle=" + tokenStyle
|
||||
+ ", dataRefreshPeriod=" + dataRefreshPeriod + ", tokenSessionCheckLogin=" + tokenSessionCheckLogin
|
||||
+ ", autoRenew=" + autoRenew + ", cookieDomain=" + cookieDomain + ", tokenPrefix=" + tokenPrefix
|
||||
+ ", isPrint=" + isPrint + ", isLog=" + isLog + ", jwtSecretKey=" + jwtSecretKey + ", idTokenTimeout="
|
||||
+ idTokenTimeout + ", basic=" + basic + ", currDomain=" + currDomain + ", sso=" + sso + "]";
|
||||
+ ", dataRefreshPeriod=" + dataRefreshPeriod
|
||||
+ ", tokenSessionCheckLogin=" + tokenSessionCheckLogin
|
||||
+ ", autoRenew=" + autoRenew
|
||||
+ ", tokenPrefix=" + tokenPrefix
|
||||
+ ", isPrint=" + isPrint
|
||||
+ ", isLog=" + isLog
|
||||
+ ", jwtSecretKey=" + jwtSecretKey
|
||||
+ ", idTokenTimeout=" + idTokenTimeout
|
||||
+ ", basic=" + basic
|
||||
+ ", currDomain=" + currDomain
|
||||
+ ", sso=" + sso
|
||||
+ ", cookie=" + cookie
|
||||
+ "]";
|
||||
}
|
||||
|
||||
|
||||
@ -503,4 +482,25 @@ public class SaTokenConfig implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 getCookie().getDomain() ,使用方式保持不变 </h1>
|
||||
* @return 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景
|
||||
*/
|
||||
@Deprecated
|
||||
public String getCookieDomain() {
|
||||
return getCookie().getDomain();
|
||||
}
|
||||
|
||||
/**
|
||||
* <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 getCookie().setDomain() ,使用方式保持不变 </h1>
|
||||
* @param cookieDomain 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景
|
||||
* @return 对象自身
|
||||
*/
|
||||
@Deprecated
|
||||
public SaTokenConfig setCookieDomain(String cookieDomain) {
|
||||
this.getCookie().setDomain(cookieDomain);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,275 @@
|
||||
package cn.dev33.satoken.context.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* Cookie Model
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaCookie {
|
||||
|
||||
/**
|
||||
* 写入响应头时使用的key
|
||||
*/
|
||||
public static final String HEADER_NAME = "Set-Cookie";
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* 有效时长 (单位:秒),-1代表为临时Cookie 浏览器关闭后自动删除
|
||||
*/
|
||||
private int maxAge = -1;
|
||||
|
||||
/**
|
||||
* 域
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 路径
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 是否只在 https 协议下有效
|
||||
*/
|
||||
private Boolean secure = false;
|
||||
|
||||
/**
|
||||
* 是否禁止 js 操作 Cookie
|
||||
*/
|
||||
private Boolean httpOnly = false;
|
||||
|
||||
/**
|
||||
* 第三方限制级别(Strict=完全禁止,Lax=部分允许,None=不限制)
|
||||
*/
|
||||
private String sameSite;
|
||||
|
||||
|
||||
/**
|
||||
* 构造一个
|
||||
*/
|
||||
public SaCookie() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造一个
|
||||
* @param name 名字
|
||||
* @param value 值
|
||||
*/
|
||||
public SaCookie(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return 名称
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name 名称
|
||||
*/
|
||||
public SaCookie setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 值
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value 值
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookie setValue(String value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 有效时长 (单位:秒),-1代表为临时Cookie 浏览器关闭后自动删除
|
||||
*/
|
||||
public int getMaxAge() {
|
||||
return maxAge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param maxAge 有效时长 (单位:秒),-1代表为临时Cookie 浏览器关闭后自动删除
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookie setMaxAge(int maxAge) {
|
||||
this.maxAge = maxAge;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 域
|
||||
*/
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param domain 域
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookie setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 路径
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path 路径
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookie setPath(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 是否只在 https 协议下有效
|
||||
*/
|
||||
public Boolean getSecure() {
|
||||
return secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param secure 是否只在 https 协议下有效
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookie setSecure(Boolean secure) {
|
||||
this.secure = secure;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 是否禁止 js 操作 Cookie
|
||||
*/
|
||||
public Boolean getHttpOnly() {
|
||||
return httpOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param httpOnly 是否禁止 js 操作 Cookie
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookie setHttpOnly(Boolean httpOnly) {
|
||||
this.httpOnly = httpOnly;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 第三方限制级别(Strict=完全禁止,Lax=部分允许,None=不限制)
|
||||
*/
|
||||
public String getSameSite() {
|
||||
return sameSite;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sameSite 第三方限制级别(Strict=完全禁止,Lax=部分允许,None=不限制)
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaCookie setSameSite(String sameSite) {
|
||||
this.sameSite = sameSite;
|
||||
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 + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建一下
|
||||
*/
|
||||
public void builde() {
|
||||
if(path == null) {
|
||||
path = "/";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为响应头 Set-Cookie 参数需要的值
|
||||
* @return /
|
||||
*/
|
||||
public String toHeaderValue() {
|
||||
this.builde();
|
||||
|
||||
if(SaFoxUtil.isEmpty(name)) {
|
||||
throw new SaTokenException("name不能为空");
|
||||
}
|
||||
if(value != null && value.indexOf(";") > -1) {
|
||||
throw new SaTokenException("无效Value:" + value);
|
||||
}
|
||||
|
||||
// Set-Cookie: name=value; Max-Age=100000; Expires=Tue, 05-Oct-2021 20:28:17 GMT; Domain=localhost; Path=/; Secure; HttpOnly; SameSite=Lax
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(name + "=" + value);
|
||||
|
||||
if(maxAge >= 0) {
|
||||
sb.append("; Max-Age=" + maxAge);
|
||||
String expires;
|
||||
if(maxAge == 0) {
|
||||
expires = Instant.EPOCH.atOffset(ZoneOffset.UTC).format(DateTimeFormatter.RFC_1123_DATE_TIME);
|
||||
} else {
|
||||
expires = OffsetDateTime.now().plusSeconds(maxAge).format(DateTimeFormatter.RFC_1123_DATE_TIME);
|
||||
}
|
||||
sb.append("; Expires=" + expires);
|
||||
}
|
||||
if(SaFoxUtil.isEmpty(domain) == false) {
|
||||
sb.append("; Domain=" + domain);
|
||||
}
|
||||
if(SaFoxUtil.isEmpty(path) == false) {
|
||||
sb.append("; Path=" + path);
|
||||
}
|
||||
if(secure) {
|
||||
sb.append("; Secure");
|
||||
}
|
||||
if(httpOnly) {
|
||||
sb.append("; HttpOnly");
|
||||
}
|
||||
if(SaFoxUtil.isEmpty(sameSite) == false) {
|
||||
sb.append("; sameSite=" + sameSite);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
@ -17,7 +17,9 @@ public interface SaResponse {
|
||||
* 删除指定Cookie
|
||||
* @param name Cookie名称
|
||||
*/
|
||||
public void deleteCookie(String name);
|
||||
public default void deleteCookie(String name) {
|
||||
addCookie(name, null, null, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入指定Cookie
|
||||
@ -28,21 +30,17 @@ public interface SaResponse {
|
||||
* @param timeout 过期时间 (秒)
|
||||
*/
|
||||
public default void addCookie(String name, String value, String path, String domain, int timeout) {
|
||||
this.addCookie(name, value, path, domain, timeout, false, false);
|
||||
this.addCookie(new SaCookie(name, value).setPath(path).setDomain(domain).setMaxAge(timeout));
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入指定Cookie
|
||||
* @param name Cookie名称
|
||||
* @param value Cookie值
|
||||
* @param path Cookie路径
|
||||
* @param domain Cookie的作用域
|
||||
* @param timeout 过期时间 (秒)
|
||||
* @param isHttpOnly 是否为HttpOnly
|
||||
* @param isSecure 是否为Secure
|
||||
* @param cookie Cookie-Model
|
||||
*/
|
||||
public void addCookie(String name, String value, String path, String domain, int timeout, boolean isHttpOnly, boolean isSecure);
|
||||
|
||||
public default void addCookie(SaCookie cookie) {
|
||||
this.addHeader(SaCookie.HEADER_NAME, cookie.toHeaderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置响应状态码
|
||||
* @param sc 响应状态码
|
||||
@ -57,6 +55,14 @@ public interface SaResponse {
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaResponse setHeader(String name, String value);
|
||||
|
||||
/**
|
||||
* 在响应头里添加一个值
|
||||
* @param name 名字
|
||||
* @param value 值
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaResponse addHeader(String name, String value);
|
||||
|
||||
/**
|
||||
* 在响应头写入 [Server] 服务器名称
|
||||
|
@ -12,10 +12,11 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||
import cn.dev33.satoken.annotation.SaCheckSafe;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.dev33.satoken.config.SaCookieConfig;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaCookie;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.exception.DisableLoginException;
|
||||
@ -110,13 +111,31 @@ public class StpLogic {
|
||||
storage.set(splicingKeyJustCreatedSave(), tokenValue);
|
||||
}
|
||||
|
||||
// 2. 将token保存到[Cookie]里
|
||||
// 2. 将 Token 保存到 [Cookie] 里
|
||||
if (config.getIsReadCookie()) {
|
||||
SaResponse response = SaHolder.getResponse();
|
||||
response.addCookie(getTokenName(), tokenValue, "/",
|
||||
config.getCookieDomain(), cookieTimeout, config.getIsCookieHttpOnly(), config.getIsCookieSecure());
|
||||
setTokenValueToCookie(tokenValue, cookieTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Token 保存到 [Cookie] 里
|
||||
* @param tokenValue token值
|
||||
* @param cookieTimeout Cookie存活时间(秒)
|
||||
*/
|
||||
public void setTokenValueToCookie(String tokenValue, int cookieTimeout){
|
||||
SaCookieConfig cfg = getConfig().getCookie();
|
||||
SaCookie cookie = new SaCookie()
|
||||
.setName(getTokenName())
|
||||
.setValue(tokenValue)
|
||||
.setMaxAge(cookieTimeout)
|
||||
.setDomain(cfg.getDomain())
|
||||
.setPath(cfg.getPath())
|
||||
.setSecure(cfg.getSecure())
|
||||
.setHttpOnly(cfg.getHttpOnly())
|
||||
.setSameSite(cfg.getSameSite())
|
||||
;
|
||||
SaHolder.getResponse().addCookie(cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前TokenValue
|
||||
|
@ -133,7 +133,7 @@ public class SaTokenJwtUtil {
|
||||
String tokenValue = createTokenValue(loginId);
|
||||
storage.set(splicingKeyJustCreatedSave(), tokenValue); // 将token保存到本次request里
|
||||
if(config.getIsReadCookie() == true){ // cookie注入
|
||||
SaManager.getSaTokenContext().getResponse().addCookie(getTokenName(), tokenValue, "/", config.getCookieDomain(), (int)config.getTimeout());
|
||||
SaManager.getSaTokenContext().getResponse().addCookie(getTokenName(), tokenValue, "/", config.getCookie().getDomain(), (int)config.getTimeout());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 注册注解拦截器
|
||||
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**").excludePathPatterns("");
|
||||
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,7 +239,7 @@ public class TestController {
|
||||
// 测试 浏览器访问: http://localhost:8081/test/test
|
||||
@RequestMapping("test")
|
||||
public AjaxJson test() {
|
||||
System.out.println("进来了");
|
||||
System.out.println("------------进来了");
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
@ -249,6 +249,4 @@ public class TestController {
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ sa-token:
|
||||
token-style: uuid
|
||||
# 是否输出操作日志
|
||||
is-log: false
|
||||
|
||||
|
||||
spring:
|
||||
# redis配置
|
||||
redis:
|
||||
|
@ -3,12 +3,9 @@ package cn.dev33.satoken.reactor.model;
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
import org.springframework.http.ResponseCookie.ResponseCookieBuilder;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* Response for Reactor
|
||||
@ -38,43 +35,6 @@ public class SaResponseForReactor implements SaResponse {
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定Cookie
|
||||
*/
|
||||
@Override
|
||||
public void deleteCookie(String name) {
|
||||
addCookie(name, null, null, null, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入指定Cookie
|
||||
*/
|
||||
@Override
|
||||
public void addCookie(String name, String value, String path, String domain, int timeout, boolean isHttpOnly, boolean isSecure) {
|
||||
// 构建CookieBuilder
|
||||
ResponseCookieBuilder builder = ResponseCookie.from(name, value)
|
||||
.domain(domain)
|
||||
.path(path)
|
||||
.maxAge(timeout)
|
||||
.httpOnly(isHttpOnly)
|
||||
.secure(isSecure)
|
||||
;
|
||||
|
||||
// set path
|
||||
if(SaFoxUtil.isEmpty(path) == true) {
|
||||
path = "/";
|
||||
}
|
||||
builder.path(path);
|
||||
|
||||
// set domain
|
||||
if(SaFoxUtil.isEmpty(domain) == false) {
|
||||
builder.domain(domain);
|
||||
}
|
||||
|
||||
// 写入Cookie
|
||||
response.addCookie(builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置响应状态码
|
||||
*/
|
||||
@ -93,6 +53,17 @@ public class SaResponseForReactor implements SaResponse {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在响应头里添加一个值
|
||||
* @param name 名字
|
||||
* @param value 值
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaResponse addHeader(String name, String value) {
|
||||
response.getHeaders().add(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重定向
|
||||
*/
|
||||
|
@ -2,12 +2,10 @@ package cn.dev33.satoken.servlet.model;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* Response for Servlet
|
||||
@ -37,33 +35,6 @@ public class SaResponseForServlet implements SaResponse {
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定Cookie
|
||||
*/
|
||||
@Override
|
||||
public void deleteCookie(String name) {
|
||||
addCookie(name, null, null, null, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入指定Cookie
|
||||
*/
|
||||
@Override
|
||||
public void addCookie(String name, String value, String path, String domain, int timeout, boolean isHttpOnly, boolean isSecure) {
|
||||
Cookie cookie = new Cookie(name, value);
|
||||
if(SaFoxUtil.isEmpty(path) == true) {
|
||||
path = "/";
|
||||
}
|
||||
if(SaFoxUtil.isEmpty(domain) == false) {
|
||||
cookie.setDomain(domain);
|
||||
}
|
||||
cookie.setPath(path);
|
||||
cookie.setMaxAge(timeout);
|
||||
cookie.setHttpOnly(isHttpOnly);
|
||||
cookie.setSecure(isSecure);
|
||||
response.addCookie(cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置响应状态码
|
||||
*/
|
||||
@ -82,6 +53,17 @@ public class SaResponseForServlet implements SaResponse {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在响应头里添加一个值
|
||||
* @param name 名字
|
||||
* @param value 值
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaResponse addHeader(String name, String value) {
|
||||
response.addHeader(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重定向
|
||||
*/
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.dev33.satoken.solon.model;
|
||||
|
||||
import org.noear.solon.Utils;
|
||||
import org.noear.solon.core.handle.Context;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
@ -22,20 +21,6 @@ public class SaResponseForSolon implements SaResponse {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCookie(String s) {
|
||||
ctx.cookieRemove(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCookie(String name, String value, String path, String domain, int timeout, boolean isHttpOnly, boolean isSecure) {
|
||||
if (Utils.isNotEmpty(path)) {
|
||||
path = "/";
|
||||
}
|
||||
|
||||
ctx.cookieSet(name, value, domain, path, timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaResponse setStatus(int sc) {
|
||||
ctx.status(sc);
|
||||
@ -47,6 +32,17 @@ public class SaResponseForSolon implements SaResponse {
|
||||
ctx.headerSet(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在响应头里添加一个值
|
||||
* @param name 名字
|
||||
* @param value 值
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaResponse addHeader(String name, String value) {
|
||||
ctx.headerAdd(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object redirect(String url) {
|
||||
|
Loading…
Reference in New Issue
Block a user