0.記事内容
ログイン時に存在しないメールアドレスまたは不正なパスワードが入力された場合に、ログイン画面にエラーメッセージを表示する場合に必要な実装について記す。
1. カスタムエラーメッセージの設定
Spring Securityの AuthenticationFailureHandler
を実装して、失敗時の処理をカスタマイズします。
CustomAuthenticationFailureHandler.java
package com.app.cook_diary.security;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
// エラーメッセージをリクエストに追加
request.setAttribute("error", "メールアドレスまたはパスワードが正しくありません。");
// エラーメッセージをログイン画面に渡すクエリパラメータを追加してリダイレクト
response.sendRedirect("/login?error=true");
}
}
2. Spring Security設定に追加
Spring Securityの設定で、カスタム AuthenticationFailureHandler
を登録します。
SecurityConfig.java
package com.app.cook_diary.config;
import com.app.cook_diary.security.CustomAuthenticationFailureHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, CustomAuthenticationFailureHandler failureHandler) throws Exception {
http.csrf(AbstractHttpConfigurer::disable) // 必要に応じて無効化
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/register", "/login", "/css/**", "/js/**").permitAll()
.anyRequest().authenticated()
) // 他は認証が必要
.formLogin(form -> form
.loginPage("/login") // ログイン画面のURL
.usernameParameter("username") // ユーザー名にメールアドレスを使用
.passwordParameter("password") // パスワードのパラメータ名
.failureHandler(failureHandler) // カスタムハンドラーを設定
.defaultSuccessUrl("/dishes", true) // 認証成功後のリダイレクト先
.permitAll() // ログインページは全員アクセス可能
)
.logout(logout -> logout
.logoutUrl("/logout") // ログアウトのURL
.logoutSuccessUrl("/") // ログアウト成功後のリダイレクト先
.permitAll() // ログアウトは全員アクセス可能
);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
3. ログイン用コントローラ
クエリパラメータ(error=true)が付与されている場合にエラーメッセージを表示するよう実装
LoginController.java
package com.app.cook_diary.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class LoginController {
@GetMapping("/login")
public String showLoginPage(@RequestParam(value = "error", required = false) String error, Model model) {
if (error != null) {
model.addAttribute("errorMessage", "メールアドレスまたはパスワードが正しくありません。");
}
return "login";
}
}
4. ログイン画面でエラーメッセージを表示
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="ja">
<head>
<meta charset="UTF-8">
<title>ログイン</title>
<link rel="stylesheet" th:href="@{/css/login.css}">
</head>
<body>
<h1>ログイン</h1>
<!-- エラーメッセージの表示 -->
<div th:if="${errorMessage}" style="color: red;">
<p th:text="${errorMessage}"></p>
</div>
<form th:action="@{/login}" method="post">
<label for="email">Email:</label>
<input type="email" id="email" name="username" required>
<br>
<label for="password">パスワード:</label>
<input type="password" id="password" name="password" required>
<br>
<button type="submit">ログイン</button>
</form>
<a th:href="@{/register}">新規登録</a>
</body>
</html>
5. 動作確認
- 誤ったメールアドレスまたはパスワードを入力してログインを試みる。
-
/login?error=true
にリダイレクトされ、エラーメッセージが表示される。
以上