【Spring Security】登入失敗後,Spring Boot 回傳 401 狀態碼,前端瀏覽器畫面彈出重新輸入帳密的彈窗,教你如何禁用彈窗!
最後更新日期:2024年08月24日
問題原因
在前後端分離架構下,當登入失敗後,後端回傳 401 狀態碼給前端,
會在 response header 添加Www-Authenticate
屬性,Basic realm="Realm"
屬性值,
瀏覽器收到這種 response header 類型,就會彈出輸入帳密的彈窗
※
realm (n.) 領域
解決方法
如果要讓前端停止彈出輸入帳密的彈窗,可以透過改寫 response 的 header,
Spring Security 返回客製化的 401 狀態碼可以參考這篇 【Spring Security】使用 postman 請求一個有 spring security 保護的 api,登入失敗回傳 401 狀態碼 ,但使用前端後分離的 vue 請求同樣的api,卻是回傳 302 狀態碼
把 response header 改寫為 response.setHeader("Www-Authenticate", "FormBased")
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
// 改寫 Response Header Www-Authenticate,防止認證失敗時,前端彈出重新輸入帳密的彈窗
response.setHeader("Www-Authenticate", "FormBased");
response.setStatus(HttpStatus.UNAUTHORIZED.value()); // 回傳 401 狀態碼
response.getWriter().write("Unauthorized");
}
}
重啟後測試看看
登入失敗後,直接返回一個 401 狀態碼
Response Header 的 Www-Authenticate
屬性確實改為 FormBased
這樣瀏覽器就不會自動跳出輸入帳密的彈窗了!
參考資料
- 登录报错后,状态码是401并弹出登录框
- ChatGPT