SpringBootで会員登録した際にログインを行いたい
Q&A
解決したいこと
会員登録した際にログイン画面へ戻ってしまう。
発生している問題・エラー
なし
該当するソースコード
package com.example.portfolio.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
http
.authorizeHttpRequests((requests)->requests
.requestMatchers("/css/**", "/images/**", "/js/**", "/storage/**", "/signup/**", "/subscription/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin((form)->form
.loginPage("/login")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/?loggedIn")
.failureUrl("/login?error")
.permitAll()
)
.logout((logout)->logout
.logoutSuccessUrl("/login?logout")
.permitAll()
);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<div th:replace="~{fragment::meta}"></div>
<div th:replace="~{fragment::styles}"></div>
<title>会員登録</title>
</head>
<body>
<div class="nagoyameshi-wrapper">
<!-- ヘッダー-->
<header>
<nav class="container nagoyameshi-container">
<div class="navbar navbar-expand-md navbar-light nagoyameshi-navbar">
<a class="navbar-brand" >
<img class="nagoyameshi-logo" th:src="@{/images/logo.png}" alt="NAGOYAMESHI">
</a>
</div>
</nav>
</header>
<main>
<div class="container pt-4 pb-5 nagoyameshi-container">
<div class="row justify-content-center">
<div class="col-xl-5 col-lg-6 col-md-8">
<h1 class="mb-4 text-center">会員登録</h1>
<form method="post" th:action="@{/signup}" th:object="${signupForm}">
<!-- 名前 -->
<div class="form-group row mb-3">
<div class="col-md-5">
<label for="name" class="col-form-label text-md-left fw-bold">
<div class="d-flex align-items-center">
<span class="me-1">名前</span>
<span class="badge bg-danger">必須</span>
</div>
</label>
</div>
<div class="col-md-7">
<div th:if="${#fields.hasErrors('name')}" class="text-danger small mb-2" th:errors="*{name}"></div>
<input type="text" class="form-control" th:field="*{name}" autocomplete="name" autofocus placeholder="田中 太郎">
</div>
</div>
<!-- フリガナ -->
<div class="form-group row mb-3">
<div class="col-md-5">
<label for="furigana" class="col-form-label text-md-left fw-bold">
<div class="d-flex align-items-center">
<span class="me-1">フリガナ</span>
<span class="badge bg-danger">必須</span>
</div>
</label>
</div>
<div class="col-md-7">
<div th:if="${#fields.hasErrors('furigana')}" class="text-danger small mb-2" th:errors="*{furigana}"></div>
<input type="text" class="form-control" th:field="*{furigana}" placeholder="タナカ タロウ">
</div>
</div>
<!-- 電話番号 -->
<div class="form-group row mb-3">
<div class="col-md-5">
<label for="phoneNumber" class="col-form-label text-md-left fw-bold">
<div class="d-flex align-items-center">
<span class="me-1">電話番号</span>
<span class="badge bg-danger">必須</span>
</div>
</label>
</div>
<div class="col-md-7">
<div th:if="${#fields.hasErrors('phoneNumber')}" class="text-danger small mb-2" th:errors="*{phoneNumber}"></div>
<input type="text" class="form-control" th:field="*{phoneNumber}" autocomplete="tel-national" placeholder="080-1234-5678">
</div>
</div>
<!-- メールアドレス -->
<div class="form-group row mb-3">
<div class="col-md-5">
<label for="email" class="col-form-label text-md-left fw-bold">
<div class="d-flex align-items-center">
<span class="me-1">メールアドレス</span>
<span class="badge bg-danger">必須</span>
</div>
</label>
</div>
<div class="col-md-7">
<div th:if="${#fields.hasErrors('email')}" class="text-danger small mb-2" th:errors="*{email}"></div>
<input type="text" class="form-control" th:field="*{email}" autocomplete="email" placeholder="taro.samurai@example.com">
</div>
</div>
<!-- 生年月日 -->
<div class="form-group row mb-3">
<div class="col-md-5">
<label for="birthday" class="col-form-label text-md-left fw-bold">
<div class="d-flex align-items-center">
<span class="me-1">生年月日</span>
<span class="badge bg-danger">必須</span>
</div>
</label>
</div>
<div class="col-md-7">
<div th:if="${#fields.hasErrors('birthday')}" class="text-danger small mb-2" th:errors="*{birthday}"></div>
<input type="text" class="form-control" th:field="*{birthday}" placeholder="20010123">
</div>
</div>
<!-- 職業-->
<div class="form-group row mb-3">
<div class="col-md-5">
<label for="occupation" class="col-form-label text-md-left fw-bold">
<div class="d-flex align-items-center">
<span class="me-1">職業</span>
<span class="badge bg-danger">必須</span>
</div>
</label>
</div>
<div class="col-md-7">
<div th:if="${#fields.hasErrors('occupation')}" class="text-danger small mb-2" th:errors="*{occupation}"></div>
<select class="form-select" aria-label="Default select example" th:field="*{occupation}">
<option value="">選択してください</option>
<option value="1">公務員</option>
<option value="2">経営者・役員</option>
<option value="3">会社員</option>
<option value="4">自営業</option>
<option value="5">自由業</option>
<option value="6">専業主婦</option>
<option value="7">パート・アルバイト</option>
<option value="8">学生</option>
<option value="9">その他</option>
</select>
</div>
</div>
<!-- パスワード-->
<div class="form-group row mb-3">
<div class="col-md-5">
<label for="password" class="col-form-label text-md-left fw-bold">
<div class="d-flex align-items-center">
<span class="me-1">パスワード</span>
<span class="badge bg-danger">必須</span>
</div>
</label>
</div>
<div class="col-md-7">
<div th:if="${#fields.hasErrors('password')}" class="text-danger small mb-2" th:errors="*{password}"></div>
<input type="password" class="form-control" th:field="*{password}" autocomplete="new-password">
</div>
</div>
<!-- パスワード確認用-->
<div class="form-group row mb-3">
<div class="col-md-5">
<label for="passwordConfirmation" class="col-form-label text-md-left fw-bold">
<div class="d-flex align-items-center">
<span class="me-1">パスワード(確認用)</span>
<span class="badge bg-danger">必須</span>
</div>
</label>
</div>
<div class="col-md-7">
<div th:if="${#fields.hasErrors('passwordConfirmation')}" class="text-danger small mb-2" th:errors="*{passwordConfirmation}"></div>
<input type="password" class="form-control" th:field="*{passwordConfirmation}" autocomplete="new-password">
</div>
</div>
<!--会員種類-->
<div class="form-group row mb-3">
<div class="col-md-5">
<label for="roleId" class="col-form-label text-md-left fw-bold">
<div class="d-flex align-items-center">
<span class="me-1">会員種類</span>
<span class="badge bg-danger">必須</span>
</div>
</label>
</div>
<div class="col-md-7">
<div th:if="${#fields.hasErrors('role')}" class="text-danger small mb-2" th:errors="*{role}"></div>
<select class="form-select" aria-label="Default select example" th:field="*{role}">
<option value="">選択してください</option>
<option value="ROLE_FREE">無料会員</option>
<option value="ROLE_PAID">有料会員</option>
</select>
</div>
</div>
<div class="form-group d-flex justify-content-center my-4">
<button type="submit" class="btn text-white w-50 nagoyameshi-btn">ログイン</button>
</div>
</form>
</div>
</div>
</div>
</main>
<div th:replace="~{fragment::footer}"></div>
</div>
<div th:replace="~{fragment::scripts}"></div>
</body>
</html>
package com.example.portfolio.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.example.portfolio.form.SignupForm;
import com.example.portfolio.service.SendMailService;
import com.example.portfolio.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
@Controller
public class AuthController {
private final UserService userService;
private final SendMailService sendMailService;
public AuthController(UserService userService, SendMailService sendMailService) {
this.userService = userService;
this.sendMailService = sendMailService;
}
@GetMapping("/login")
public String login(){
return "auth/login";
}
@GetMapping("/signup")
public String signup(Model model){
model.addAttribute("signupForm", new SignupForm());
return "auth/signup";
}
@PostMapping("/signup")
public String signup(@ModelAttribute @Validated SignupForm signupForm,
BindingResult bindingResult,
RedirectAttributes redirectAttributes,
HttpServletRequest httpServletRequest,
Model model
) {
if(userService.isEmailRegistered(signupForm.getEmail())) {
FieldError fieldError = new FieldError(bindingResult.getObjectName(), "email", "すでに登録済みのメールアドレスです。");
bindingResult.addError(fieldError);
}
if(!userService.isSamePassword(signupForm.getPassword(), signupForm.getPasswordConfirmation())) {
FieldError fieldError2 = new FieldError(bindingResult.getObjectName(), "password", "パスワードが一致しません。");
bindingResult.addError(fieldError2);
}
if(bindingResult.hasErrors()) {
return "auth/signup";
}
if(signupForm.getRole().equals("ROLE_PAID")) {
model.addAttribute("signupForm", signupForm);
return "/subscription/index";
} else {
userService.create(signupForm);
sendMailService.sendMailSignup(signupForm);
redirectAttributes.addFlashAttribute("successMessage", "会員登録が完了しました。");
return "redirect:/";
}
}
}
他に必要なコードがあれば追記します。
自分で試したこと
WebSecurityConfigの.formLoginの部分に.loginPage("/signup")を追加してみたができませんでした。
0