1. 概述
為了網絡優化,某些網站允許瀏覽器在本地存儲中緩存資源,如 CSS 或 JS。這使得瀏覽器可以為每次請求節省一次網絡往返。
因此,緩存資源對於提高網頁加載時間至關重要。同樣重要的是,在不再需要時清除緩存數據。 例如, 如果用户註銷網站,瀏覽器應從緩存中刪除所有會話數據。
瀏覽器存儲數據時間超過需要的時間存在兩個主要問題:
- 現代網站使用大量的 CSS 和 JS 文件,消耗大量的瀏覽器內存
- 緩存敏感數據(如會話 Cookie)的網站容易受到釣魚攻擊
在本教程中,我們將看到 HTTP 的 Clear-Site-Data 響應頭如何幫助網站清除瀏覽器中本地存儲的數據。
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 中添加 Clear-Site-Data 標題之前,讓我們將 spring-security-web 和 spring-security-config 依賴項添加到項目中:
<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 in 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 GMT
}
5. 結論
在本文中,我們研究了瀏覽器即使在不需要的情況下也緩存關鍵的用户數據的影響。例如,瀏覽器不應在用户註銷網站後緩存數據。
然後,我們看到了 HTTP 的 Clear-Site-Data 響應頭允許網站強制瀏覽器清除本地緩存數據。
最後,我們在 Spring Security 中實施了一個註銷頁面,並使用 ClearSiteDataHeaderWriter 在控制器響應中添加此標頭。