接下來,在開始處理註冊和登入前,我們先設定Spring Security。
在上一個專案有提到CSRF,當時我們沒有真正的處理這個問題,這次會導入JSON Web Token(JWT)來解決CSRF。
JWT是一種身份驗證的方式,看到有效的JWT就代表是本人的操作。
這有點像古代的尚方寶劍,有了尚方寶劍就能行使權利,壞人拿到也能為所欲為。因此保護好JWT非常重要。
新增SecurityConfig.java,和之前一樣透過SecurityFilterChain設定Spring Security。
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
將session設定成無狀態,代表的是,不會讀取後端儲存的session,需要在前端將需要的內容傳入,代表保持登入的功能由前端負責。
如果我們在前端沒有傳Token給後端,後端一律當成未登入,不管之前是否登入過。
後端是這樣的,前端只要專心管理網頁,與後端溝通,做保持登入的功能就可以。
可是後端要考慮的事情就很多了,儲存的session會不會占滿伺服器的硬碟,讀取session時的CPU使用率,所以這個功能讓前端處理比較好。
httpSecurity.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
api開頭的網址需要有權限才能操作,其餘可直接通過
.authorizeHttpRequests(authorizeHttpRequests -> authorizeHttpRequests.requestMatchers("/api/**").authenticated().anyRequest().permitAll())
這幾個網址可以直接通過
localhost:8080/hello/ ✔️
localhost:8080/test/ ✔️
下面的需要驗證
localhost:8080/api/ ⚠️
localhost:8080/api/hello ⚠️
關閉CSRF防護,我們之後會使用JWT防禦CSRF攻擊。
.csrf(csrf -> csrf.disable())
雖然我們這個Spring Boot專案只會做後端的部分,如果以後要讓前端存取後端時,會顯示CORS開頭的錯誤,在後端可以解決這個問題,讓前端可以和後端交流,提供給大家參考,不需要加入到SecurityConfig中。
.cors(cors -> cors.configurationSource(new CorsConfigurationSource() {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
CorsConfiguration config = new CorsConfiguration();
允許的前端網址來源
config.setAllowedOrigins(Arrays.asList(
"前端的網址,例如http://localhost:5173"
));
允許的HTTP request methods
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
config.setAllowCredentials(true);
第一層過濾HTTP Header,允許JWT通過
config.setExposedHeaders(Arrays.asList("Authorization"));
第二層過濾HTTP Header,讓JWT通過
config.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
通過後3600秒內,不會再次檢查同樣的request
config.setMaxAge(3600L);
return config;
}
}));
設定密碼雜湊函式,可以將10修改更大數字,讓密碼經過更多次的運算,但是也需要耗費更多時間雜湊密碼。
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(10);
}