SpringとJPAをベースにしたWebアプリケーションの開発#37パスワードを忘れました.(+Spring MVCのフォーム処理モードの復習)
43981 ワード
SpringとJPAをベースにしたWebアプリケーションの開発#37パスワードを忘れました.
これらはインフラストラクチャ、Spring、JPAベースのWebアプリケーション開発のコースに基づいて作成されています.
要約は、学習コース、要約ソースのタグ付け、ブログまたはドキュメント形式で公開できるようにする原則の下で公開されます.出典は前述の通り、インフラストラクチャ、Spring、JPAベースのWebアプリケーション開発.
私が勉強しているソースコードはhttps://github.com/n00nietzsche/jakestudy_webappにアップロードされます.私は伝言ごとに講義のどの部分を記録します.
のパスワードを忘れた場合は、Eメールで「ログイン可能リンク」を送信します.メールで送信したリンクをクリックしてログインします. Eメールを入力できるフォームが表示され、リンク転送ボタンが表示されます. に入力されたEメールに対応するアカウントを検索します.もしそうであれば、Eメールでログイン可能なリンクを送信します. Eメールを送信すると、プロンプトが表示されます. TokenとEメールを確認し、アカウントにログインします.
また、
これらはインフラストラクチャ、Spring、JPAベースのWebアプリケーション開発のコースに基づいて作成されています.
要約は、学習コース、要約ソースのタグ付け、ブログまたはドキュメント形式で公開できるようにする原則の下で公開されます.出典は前述の通り、インフラストラクチャ、Spring、JPAベースのWebアプリケーション開発.
私が勉強しているソースコードはhttps://github.com/n00nietzsche/jakestudy_webappにアップロードされます.私は伝言ごとに講義のどの部分を記録します.
パスワードを忘れました。
GET /email-login
POST /email-login
GET /login-by-email
1.Form Backingオブジェクトの作成
@Data
public class EmailForm {
@Email
@NotBlank
private String email;
}
これはjavax.validation
を用いて基本検証を行う場所であり、将来ModelMapper
またはsetterによってドメインオブジェクトに統合される情報を保存する場所でもある.2.Validatorの作成(オプション)
@Component
@RequiredArgsConstructor
public class EmailFormValidator implements Validator {
private final AccountRepository accountRepository;
@Override
public boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(EmailForm.class);
}
@Override
public void validate(Object target, Errors errors) {
EmailForm emailForm = (EmailForm) target;
if(!accountRepository.existsByEmail(emailForm.getEmail())) {
errors.rejectValue("email", "not.exist.email", new Object[]{emailForm.getEmail()}, "존재하지 않는 이메일 입니다.");
}
}
}
repositoryなどのゲストで検証する際に主に使用するValidator
が必要です.認証に失敗した場合、Errors
オブジェクトがコントローラに送信され、認証に失敗した場合に論理を記述します.3.コントローラの作成
3.1. initBinder()の作成
@InitBinder("emailForm")
public void initBinderEmailForm(WebDataBinder webDataBinder) {
webDataBinder.addValidators(emailFormValidator);
}
Validator
が完成したら登録してください.3.2. GPRGとビジネスロジックの作成
@GetMapping("/login-by-email")
public String loginByEmailForm(Model model) {
model.addAttribute(new EmailForm());
return "/login-by-email";
}
@PostMapping("/login-by-email")
public String loginByEmail(@Valid @ModelAttribute EmailForm emailForm, Errors errors, RedirectAttributes redirectAttributes, Model model) {
if(errors.hasErrors()) {
// model.addAttribute("error", "에러 발생");
return "/login-by-email";
}
if(accountService.sendLoginConfirmEmail(emailForm.getEmail())) {
redirectAttributes.addFlashAttribute("message", "이메일이 전송되었습니다. 이메일을 확인해주세요.");
}else {
redirectAttributes.addFlashAttribute("error", "이미 이메일을 재전송했습니다. 1시간 이내에 이메일을 재전송 할 수 없습니다.");
}
return "redirect:/login-by-email";
}
@GetMapping("/check-login-token")
public String checkLoginToken(String token, String email, RedirectAttributes redirectAttributes, Model model) {
Account account = accountRepository.findByEmail(email);
if (account == null || !account.isValidLoginCheckToken(token)) {
redirectAttributes.addFlashAttribute("error", "토큰 혹은 이메일이 잘못되었습니다.");
return "redirect:/login-by-email";
}
accountService.login(account);
return "redirect:/";
}
失敗した場合はredirect:/
を積極的に利用する./login-by-email
と同じパスを使用している場合、フォームに入れることができるModelAttribute
の情報がない場合は、th:object
のようなthymeleaf機能を使用するとエラーが発生するので注意してください.redirect:/
を利用すると、このような現象を容易に防止することができる.また、
POST
メソッドではビューがredirect:/
に戻ることはありません.return
に直接戻ると、リフレッシュ時に同じコンテンツがフォームに再渡され、同じコンテンツが再び渡されることに注意してください.4.サービス・エンド・メソッドの実装
public boolean sendLoginConfirmEmail(String email) {
Account account = accountRepository.findByEmail(email);
if(account.canSendLoginCheckTokenAgain()) {
account.generateLoginCheckToken();
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(account.getEmail());
simpleMailMessage.setSubject("제이크 스터디 이메일로 로그인");
simpleMailMessage.setText("/check-login-token?token=" + account.getLoginCheckToken() + "&email=" + account.getEmail());
javaMailSender.send(simpleMailMessage);
return true;
} else {
return false;
}
これは、ログイントークン確認メールを送信する部分です.確認を使用してログイン電子メールを再送信できる.canSendLoginCheckTokenAgain()
が正常に送信された後、true
に送信されない場合はfalse
に戻ります.5.合成HTML
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<title>로그인</title>
<th:block th:replace="fragments :: headLibraryInjection"></th:block>
</head>
<body class="bg-light">
<th:block th:replace="fragments :: main-nav"></th:block>
<div class="container">
<div class="py-5 text-center">
<p class="lead">스터디올래</p>
<h2>로그인</h2>
</div>
<div class="row justify-content-center">
<div th:if="${param.error}" class="alert alert-danger" role="alert">
<p>이메일이 정확하지 않습니다.</p>
</div>
<div th:if="${message}" class="alert alert-info alert-dismissible fade show mt-3" role="alert">
<span th:text="${message}">알림 메시지</span>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">x</span>
</button>
</div>
<div th:if="${error}" class="alert alert-danger alert-dismissible fade show mt-3" role="alert">
<span th:text="${error}">에러 메시지</span>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">x</span>
</button>
</div>
<!-- `th:object` 를 쓴 경우, 사용할 객체를 올바르게 모델에서 내려받지 못한 경우 500에러가 나니까 조심해야 한다. -->
<form class="needs-validation col-sm-6" th:object="${emailForm}" action="#" th:action="@{/login-by-email}" method="post" novalidate>
<div class="form-group">
<label for="username">이메일</label>
<input id="username" type="text" th:field="*{email}" class="form-control"
placeholder="[email protected]" aria-describedby="emailHelp" required />
<small id="emailHelp" class="form-text text-muted">
가입할 때 사용한 이메일을 입력하세요.
</small>
<small class="invalid-feedback">이메일을 입력하세요.</small>
<!-- `th:if`는 `Validator` 에서 `.rejectValue()` 에 넣은 `field` 값을 인식하여 에러가 있는지 확인한다. -->
<small class="form-text text-danger" th:if="${#fields.hasErrors('email')}" th:errors="*{email}">
이메일이 잘못되었습니다.
</small>
</div>
<div class="form-group">
<button class="btn btn-success btn-block" type="submit"
aria-describedby="submitHelp">로그인</button>
<small class="form-text text-muted">스터디올래에 처음 오셨다면,
<a href="#" th:href="@{/sign-up}">계정을 먼저 만드세요.</a>
</small>
</div>
</form>
</div>
<th:block th:replace="fragments :: footer"></th:block>
</div>
<script th:replace="fragments :: form-validation"></script>
</body>
</html>
Reference
この問題について(SpringとJPAをベースにしたWebアプリケーションの開発#37パスワードを忘れました.(+Spring MVCのフォーム処理モードの復習)), 我々は、より多くの情報をここで見つけました https://velog.io/@jakeseo_me/스프링과-JPA-기반-웹-애플리케이션-개발-37-패스워드를-잊어버렸습니다テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol