中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

spring-session中怎么動態修改cookie的max-age

發布時間:2021-08-03 11:25:13 來源:億速云 閱讀:392 作者:Leah 欄目:大數據

這篇文章給大家介紹spring-session中怎么動態修改cookie的max-age,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

使用spring-session時,動態修改cookie的max-age

不論是使用spring提供的spring-session,還是使用servle容器實現的http session。原理都是把session-idcookie的形式存儲在客戶端。每次請求都帶上cookie服務器通過session-id,找到session

spring-session的使用

https://springboot.io/t/topic/864

由“記住我”引發的一個問題

用戶登錄的時候,通常需要一個【記住我】的選擇框,表示是否要長期的保持會話。

【記住我】× 一般會把cookie的max-age設置為 -1,表示在瀏覽器關閉的時候,就自動的刪除cookie。對于客戶端而言關閉了瀏覽器,就是丟失了會話,需要重新的登錄系統。特別在公共場合登陸了某些系統后,忘記執行‘退出’操作,直接關閉了瀏覽器,后面使用電腦的人打開瀏覽器,也必須先登錄才可以訪問系統。這樣在一定的程度上保證了安全性。

【記住我】√ 一般在自己私人電腦上選擇,目的是為了避免重復的登錄操作。登錄成功,一般會把max-age的值設置為比較長,就算是關閉了瀏覽器。重新打開,也不需要再次執行登錄操作。

spring-session 配置cookie的max-age屬性

使用spring-session時,可以通過yml配置,或者代碼配置的形式來設置max-age的屬性。但是問題在于所有的session創建,都是使用同樣的屬性。在【記住我】這個功能上會出現一些問題

固定設置:max-age=-1,那么就算是勾選了【記住我】,也會因為瀏覽器關閉刪除cookie,而丟失會話。下次打開瀏覽器還是需要重新執行登錄

固定設置: max-age=604800(7天),那么用戶在未勾選【記住我】的情況下,關閉瀏覽器。cookie并不會被立即刪除,任何人再次打開這個系統。都不需要登錄就可以直接操作系統。

總的來說就是,固定的max-age屬性,會導致【記住我】功能失效。

使用spring-session時的解決方案

spring-session 通過接口 CookieSerializer,來完成對客戶端cookie的讀寫操作。并且提供了一個默認的實現類: DefaultCookieSerializer。我們想要動態的修改cookie的max-age屬性,核心方法在于。

@Override
public void writeCookieValue(CookieValue cookieValue) {
	...
	StringBuilder sb = new StringBuilder();
	sb.append(this.cookieName).append('=');
	...
	int maxAge = getMaxAge(cookieValue);  // 讀取maxAge屬性
	if (maxAge > -1) {
		sb.append("; Max-Age=").append(cookieValue.getCookieMaxAge());
		ZonedDateTime expires = (maxAge != 0) ? ZonedDateTime.now(this.clock).plusSeconds(maxAge)
				: Instant.EPOCH.atZone(ZoneOffset.UTC);
		sb.append("; Expires=").append(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME));
	}
	...
}
private int getMaxAge(CookieValue cookieValue) {
	int maxAge = cookieValue.getCookieMaxAge();
	if (maxAge < 0) {
		if (this.rememberMeRequestAttribute != null
				&& cookieValue.getRequest().getAttribute(this.rememberMeRequestAttribute) != null) {
			cookieValue.setCookieMaxAge(Integer.MAX_VALUE);
		}
		else if (this.cookieMaxAge != null) {
			cookieValue.setCookieMaxAge(this.cookieMaxAge);  // 如果 DefaultCookieSerializer 設置了maxAge屬性,則該屬性優先
		}
	}
	return cookieValue.getCookieMaxAge(); // cookieValue 默認的maxAge屬性 = -1
}

可以看出,spring-session并沒使用servlet提供的cookie api來響應cookie。而是自己構造Cookie頭。而且還提供了Servlet還未實現的,Cookie的新屬性:sameSite,可以用來防止csrf攻擊。

覆寫 DefaultCookieSerializer

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.session.web.http.DefaultCookieSerializer;

// @Component
public class DynamicCookieMaxAgeCookieSerializer extends DefaultCookieSerializer {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(DynamicCookieMaxAgeCookieSerializer.class);
	
	public static final String COOKIE_MAX_AGE = "cookie.max-age";
	
	@Value("${server.servlet.session.cookie.max-age}")
	private Integer cookieMaxAge;
	
	@Override
	public void writeCookieValue(CookieValue cookieValue) {
		HttpServletRequest request = cookieValue.getRequest();
		// 從request域讀取到cookie的maxAge屬性
		Object attribute = request.getAttribute(COOKIE_MAX_AGE);
		if (attribute != null) {
			cookieValue.setCookieMaxAge((int) attribute);
		} else {
			// 如果未設置,就使用默認cookie的生命周期
			cookieValue.setCookieMaxAge(this.cookieMaxAge);
		}
		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug("動態設置cooke.max-age={}", cookieValue.getCookieMaxAge());
		}
		super.writeCookieValue(cookieValue);
	}
}

原理就是,把cookie的maxAge屬性存儲到request域。在響應客戶端之前,動態的設置。

添加到IOC

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.CookieSerializer;

import com.video.manager.spring.session.DynamicCookieMaxAgeCookieSerializer;

@Configuration
public class SpringSessionConfiguration {
	
	@Value("${server.servlet.session.cookie.name}")
	private String cookieName;
	
	@Value("${server.servlet.session.cookie.secure}")
	private Boolean cookieSecure;
	
//	@Value("${server.servlet.session.cookie.max-age}")
//	private Integer cookieMaxAge;
	
	@Value("${server.servlet.session.cookie.http-only}")
	private Boolean cookieHttpOnly;

	@Value("${server.servlet.session.cookie.same-site}")
	private String cookieSameSite;
	
	@Bean
	public CookieSerializer cookieSerializer() {
		DynamicCookieMaxAgeCookieSerializer serializer = new DynamicCookieMaxAgeCookieSerializer();
		serializer.setCookieName(this.cookieName);
		// serializer.setCookieMaxAge(this.cookieMaxAge);
		serializer.setSameSite(this.cookieSameSite);
		serializer.setUseHttpOnlyCookie(this.cookieHttpOnly);
		serializer.setUseSecureCookie(this.cookieSecure);
		return serializer;
	}
}

使用 @Value,讀取yml配置中的Cookie屬性。

測試接口

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.video.manager.spring.session.DynamicCookieMaxAgeCookieSerializer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/test")
public class TestController {

	static final Logger LOGGER = LoggerFactory.getLogger(TestController.class);
	
	@GetMapping("/session")
	public ModelAndView session(HttpServletRequest request, 
			@RequestParam("remember")Boolean remember) {
		
		HttpSession httpSession = request.getSession();
		LOGGER.debug("httpSession={}", httpSession);
		
		if (!remember) {  // 不記住我
			// 設置cookie的生命周期為 -1
			request.setAttribute(DynamicCookieMaxAgeCookieSerializer.COOKIE_MAX_AGE, -1);
			// 設置session僅緩存30分鐘
			httpSession.setMaxInactiveInterval(60 * 30);
		}
		
		ModelAndView modelAndView = new ModelAndView("test/test");
		return modelAndView;
	}
}

【記住我】√

http://localhost/test/session?remember=true

響應Cookie,存儲時間是 7 天

spring-session中怎么動態修改cookie的max-age

redis的session存儲,緩存時間是7天 spring-session中怎么動態修改cookie的max-age

【記住我】×

http://localhost/test/session?remember=false

響應Cookie,存儲時間是:-1,臨時會話設置成功,瀏覽器關閉Cookie刪除

spring-session中怎么動態修改cookie的max-age

redis的session存儲,緩存時間是30分鐘,超過30分鐘不活動,自動刪除

spring-session中怎么動態修改cookie的max-age

關于spring-session中怎么動態修改cookie的max-age就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丹凤县| 肇庆市| 商都县| 辽宁省| 东港市| 屯昌县| 古蔺县| 开江县| 新昌县| 龙陵县| 乾安县| 西林县| 当雄县| 棋牌| 永泰县| 海口市| 平山县| 长兴县| 赣州市| 新田县| 安顺市| 玉门市| 安仁县| 绩溪县| 平遥县| 滦南县| 共和县| 彭山县| 民权县| 密山市| 丰镇市| 乐业县| 应用必备| 咸阳市| 崇明县| 左贡县| 十堰市| 勐海县| 辛集市| 新密市| 贵州省|