如何在 SpringBoot 中使用 cookies
原文: https://attacomsian.com/blog/cookies-spring-boot#further-reading
- 讀 HTTP Cookie
- 設(shè)置 HTTP Cookie
- 讀 All Cookies
- Cookie 的有效期
- Secure Cookie
- HttpOnly Cookie
- Cookie Scope (范圍)
- 刪除 Cooke
- 總結(jié)
HTTP Cookie(也稱為web Cookie檬果、瀏覽器Cookie)是服務(wù)器存儲(chǔ)在用戶瀏覽器中的一小塊信息。服務(wù)器在返回瀏覽器請(qǐng)求的響應(yīng)時(shí)設(shè)置cookies伴奥。瀏覽器存儲(chǔ)cookies槽卫,并將它們與下一個(gè)請(qǐng)求一起發(fā)送回同一服務(wù)器忠烛。Cookie通常用于會(huì)話管理、用戶跟蹤和存儲(chǔ)用戶首選項(xiàng)。
Cookies幫助服務(wù)器跨多個(gè)請(qǐng)求記住客戶機(jī)耘分。如果沒(méi)有cookies,服務(wù)器將把每個(gè)請(qǐng)求都當(dāng)作一個(gè)新的客戶機(jī)來(lái)處理绑警。
在本教程中求泰,我們將學(xué)習(xí)如何在SpringBoot應(yīng)用程序中讀取、設(shè)置和刪除httpcookies计盒。
Reading HTTP Cookie
Spring框架提供@CookieValue注釋來(lái)獲取任何http cookie的值渴频,而無(wú)需迭代從請(qǐng)求中獲取的所有cookie。此注釋可用于將cookie的值映射到控制器方法參數(shù)北启。
@GetMapping("/")
public String readCookie(@CookieValue(value = "username", defaultValue = "Atta") String username) {
return "Hey! My username is " + username;
}
在上面的代碼片段中卜朗,請(qǐng)注意defaultValue=“Atta”。如果未設(shè)置默認(rèn)值咕村,Spring將拋出java.lang.IllegalStateException異常在HTTP請(qǐng)求中找不到名為username的cookie時(shí)出現(xiàn)異常场钉。
Setting HTTP Cookie
要在Spring Boot中設(shè)置cookie,可以使用HttpServletResponse類的addCookie()方法培廓。您所需要做的就是創(chuàng)建一個(gè)新的Cookie類實(shí)例并將其添加到響應(yīng)中惹悄。
@GetMapping("/change-username")
public String setCookie(HttpServletResponse response) {
// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
//add cookie to response
response.addCookie(cookie);
return "Username is changed!";
}
Reading All Cookies
我們也可以使用HttpServletRequest類作為控制器方法參數(shù)來(lái)讀取所有cookie,而不是使用@CookieValue注釋肩钠。此類提供getCookies()方法泣港,該方法將瀏覽器發(fā)送的所有Cookie作為Cookie數(shù)組返回。
@GetMapping("/all-cookies")
public String readAllCookies(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
return Arrays.stream(cookies)
.map(c -> c.getName() + "=" + c.getValue()).collect(Collectors.joining(", "));
}
return "No cookies";
}
Cookie Expiration
如果沒(méi)有為cookie指定過(guò)期時(shí)間价匠,則只要會(huì)話未過(guò)期当纱,cookie就會(huì)持續(xù)。這種cookies稱為會(huì)話cookies踩窖。會(huì)話Cookie保持活動(dòng)狀態(tài)坡氯,直到用戶關(guān)閉瀏覽器或清除Cookie。上面創(chuàng)建的 username
cookie實(shí)際上是一個(gè)會(huì)話cookie。
但是您可以重寫此默認(rèn)行為箫柳,并使用cookie類的 setMaxAge()方法設(shè)置cookie過(guò)期時(shí)間手形。
// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
//add cookie to response
response.addCookie(cookie);
現(xiàn)在,用戶名cookie將在接下來(lái)的7天內(nèi)保持活動(dòng)狀態(tài)悯恍,而不是在瀏覽器關(guān)閉時(shí)過(guò)期库糠。這種cookie在指定的日期和時(shí)間過(guò)期,稱為永久cookie涮毫。
傳遞給setMaxAge()方法的過(guò)期時(shí)間以秒為單位瞬欧。過(guò)期日期和時(shí)間是相對(duì)于設(shè)置cookie的客戶端的,而不是相對(duì)于服務(wù)器的罢防。
Secure Cookie
安全cookie是僅通過(guò)加密的HTTPS連接發(fā)送到服務(wù)器的cookie艘虎。安全Cookie不能通過(guò)未加密的HTTP連接傳輸?shù)椒?wù)器。
// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
cookie.setSecure(true);
//add cookie to response
response.addCookie(cookie);
HttpOnly Cookie
HttpOnly Cookie用于防止跨站點(diǎn)腳本(XSS)攻擊咒吐,不能通過(guò)JavaScript 的Document.cookie
API 訪問(wèn)野建。當(dāng)為cookie設(shè)置HttpOnly標(biāo)志時(shí),它會(huì)告訴瀏覽器只有服務(wù)器才能訪問(wèn)此特定cookie恬叹。
// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
cookie.setSecure(true);
cookie.setHttpOnly(true);
//add cookie to response
response.addCookie(cookie);
Cookie Scope
如果未指定作用域贬墩,cookie僅發(fā)送到用于在瀏覽器中設(shè)置它的路徑的服務(wù)器。我們可以使用Cookie類的setPath()方法來(lái)更改此行為妄呕。這將設(shè)置cookie的 Path
參數(shù)。
// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setPath("/"); // global cookie accessible every where
//add cookie to response
response.addCookie(cookie);
Deleting Cookie
要?jiǎng)h除cookie嗽测,請(qǐng)將 Max-Age
參數(shù)設(shè)置為0并重置cookie的值绪励。您還必須傳遞與設(shè)置cookie屬性相同的其他cookie屬性。不要將Max-Age
參數(shù)設(shè)置為 -1唠粥。否則疏魏,瀏覽器會(huì)將其視為會(huì)話cookie。
// create a cookie
Cookie cookie = new Cookie("username", null);
cookie.setMaxAge(0);
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setPath("/");
//add cookie to response
response.addCookie(cookie);
Summary
Cookie提供了一種在服務(wù)器和瀏覽器之間交換信息的方法晤愧,用于管理會(huì)話(登錄大莫、購(gòu)物車、游戲分?jǐn)?shù))官份、記住用戶偏好(主題只厘、隱私策略接受度)以及跟蹤整個(gè)站點(diǎn)的用戶行為。
springboot提供了一種讀取舅巷、寫入和刪除httpcookies的簡(jiǎn)單方法羔味。
- @CookieValue注釋將cookie的值映射到方法參數(shù)。當(dāng)cookie不可用時(shí)钠右,應(yīng)設(shè)置默認(rèn)值以避免運(yùn)行時(shí)異常赋元。
- HttpServletResponse類可用于在瀏覽器中設(shè)置新cookie。您只需要?jiǎng)?chuàng)建Cookie類的實(shí)例并將其添加到Response中。
- 要讀取所有Cookie搁凸,可以使用HttpServletRequest的getCookies()方法媚值,該方法返回一個(gè)Cookie數(shù)組。
- Max-Age參數(shù)指定cookie過(guò)期的日期和時(shí)間护糖。
- 如果在cookie中存儲(chǔ)敏感信息褥芒,請(qǐng)確保設(shè)置Secure和HttpOnly標(biāo)志以避免XSS攻擊。
- 設(shè)置
Path=/
以使當(dāng)前域的任何地方都可以訪問(wèn)cookie椅文。 - 若要?jiǎng)h除cookie喂很,請(qǐng)將
Max-Age
設(shè)置為0,并傳遞用于設(shè)置cookie的所有屬性皆刺。
demo源碼:https://github.com/FDzhang/demo-study/tree/master/demo-springboot/demo-cookies