1. 概述
為了網絡優化,一些網站允許瀏覽器在本地存儲中緩存資源,例如 CSS 或 JS 文件。這使得瀏覽器可以為每次請求節省一次網絡往返。
因此,緩存資源對於提高網頁加載時間至關重要。同樣重要的是,在不再需要時清除緩存數據。例如,如果用户註銷網站,瀏覽器應從緩存中刪除所有會話數據。
瀏覽器緩存數據時間過長存在兩個主要問題:
- 現代網站使用大量的 CSS 和 JS 文件,消耗大量的瀏覽器內存。
- 緩存敏感數據(如會話 Cookie)的網站容易受到釣魚攻擊。
在本教程中,我們將瞭解 HTTP 的 <em >Clear-Site-Data</em> 響應頭如何幫助網站從瀏覽器中清除本地存儲的數據。
2. Clear-Site-Data 頭部
與 Cache-Control 頭部一樣,Clear-Site-Data 也是一個 HTTP 響應頭部。網站可以使用此頭部指示瀏覽器刪除本地存儲中的數據。
對於需要身份驗證的網站,Cache-Control 頭部通常包含在 /login 響應中,允許瀏覽器緩存用户數據。類似地,網站在 /logout 響應中包含 Clear-Site-Data 頭部,以清除屬於該用户的任何緩存數據。
在此,重要的是要理解瀏覽器通常將本地存儲分為不同的類型:
- 本地存儲
- 會話存儲
- Cookie
由於網站可以存儲這些類型中的任何一種數據,Clear-Site-Data 允許我們在頭部指定目標存儲:
- cache – 刪除本地緩存數據,包括私有和共享瀏覽器緩存
- cookies – 刪除存儲在瀏覽器 Cookie 中的數據
- storage – 清除瀏覽器的本地和會話存儲
- executionContexts – 此開關告訴瀏覽器為該 URL 重新加載瀏覽器標籤
- * (星號) – 從以上所有存儲區域刪除數據
因此,Clear-Site-Data 頭部必須至少包含一種這些存儲類型:
Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"在以下部分,我們將實現 Spring Security 中的一個 /logout 服務,並在響應中包含 Clear-Site-Data 標頭。
3. Maven 依賴
在編寫代碼以在 Spring 中添加 <em >Clear-Site-Data</em> 標頭之前,讓我們將 <em >spring-security-web</em> 和 <em >spring-security-config</em> 依賴項添加到項目中:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>6.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>6.1.5</version>
</dependency>4. ClearSiteDataHeaderWriter 在Spring Security中
我們之前討論過,Spring 提供一個 CacheControl 工具類,用於在響應中寫入 Cache-Control 標頭。 類似於地,Spring Security 提供一個 ClearSiteDataHeaderWriter 類,方便地在 HTTP 響應中添加該標頭。
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SpringSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.formLogin(httpSecurityFormLoginConfigurer ->
httpSecurityFormLoginConfigurer.loginPage("/login")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/homepage", true))
.logout(httpSecurityLogoutConfigurer ->
httpSecurityLogoutConfigurer.logoutUrl("/baeldung/logout")
.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES, STORAGE))));
return http.build();
}
}在這裏,我們使用 Spring Security 實現了登錄和註銷頁面。作為結果,Spring 會在所有對 /baeldung/logout 請求的響應中添加 Clear-Site-Data 頭部:
Clear-Site-Data: "cache", "cookies", "storage"如果現在我們使用 curl並向 https://localhost:8080/baeldung/logout發送請求,我們將收到以下響應頭:
{ [5 bytes data]
< HTTP/1.1 302
< Clear-Site-Data: "cache", "cookies", "storage"
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< X-Frame-Options: DENY
< Location: https://localhost:8080/login.html?logout
< Content-Length: 0
< Date: Tue, 17 Mar 2020 17:12:23 GMT5. 結論
在本文中,我們研究了瀏覽器即使在不需要的情況下也緩存關鍵用户數據的影響。例如,瀏覽器不應在用户註銷網站後緩存數據。
我們還了解到 HTTP 的 Clear-Site-Data 響應頭允許網站強制瀏覽器清除本地緩存的數據。
最後,我們使用 Spring Security 實現了一個註銷頁面,並使用 ClearSiteDataHeaderWriter 在控制器響應中添加該頭。