Gửi mail với MailTrap kết hợp Spring Boot – Thymeleaf – Elasticsearch. Xác thực với otp khi đăng nhập

Trong bài viết này, tôi hướng dẫn các bạn tạo 1 mã otp và gửi đến email của chính mình để xác thực cho mỗi lần đăng nhập. Tôi sử dụng MailTrap

Các vấn đề cần xử lý:

  • Tạo 1 model Otp, tự động sinh Otp mỗi lần đăng nhập
  • Thiết lập thời gian sống của otp
  • Gửi mail với mã Otp vừa sinh ra

Công cụ và thư viện được sử dụng trong bài viết:

  • Spring boot 2.7.4
  • Spring tool suite 4
  • Spring data elasticsearch 4.4.2
  • Maven 3
  • Java 11
  • Elasticsearch 7.17.6
  • Kaizen Elastic

Tham khảo những bài viết sau để biết cách tạo 1 project với Spring Boot – Thymeleaf – Elasticsearch:

https://viblo.asia/p/tao-1-custom-token-moi-khi-dang-nhap-va-luu-vao-database-voi-spring-boot-thymeleaf-elasticsearch-ket-hop-voi-su-dung-kaizen-elastic-tao-1-function-tai-fe-trigger-goi-den-be-xin-cap-token-moi-sau-1-khoang-thoi-gian-chi-dinh-5OXLAXjaJGr

https://viblo.asia/p/tao-mot-project-voi-spring-boot-va-elasticsearch-841-su-dung-thu-vien-spring-data-elasticsearch-huong-dan-cai-dat-va-su-khac-nhau-giua-2-phien-ban-8xx-voi-7xx-elasticsearch-Rk74aRXvJeO

https://viblo.asia/p/tao-mot-project-voi-spring-boot-thymeleaf-elasticsearch-su-dung-http2-tao-service-run-elasticsearch-yZjJYjolLOE

https://viblo.asia/p/ma-hoa-thong-tin-password-trong-qua-trinh-login-register-voi-base64-su-dung-spring-boot-thymeleaf-elasticsearch-khong-su-dung-form-bXP4WPoBJ7G

Nguồn template: https://bbbootstrap.com/snippets/bootstrap-mobile-phone-verification-form-using-otp-78737873#

1. Cấu trúc project:

image.png

2. Package “com.example.otp.application”:

Nội dung class “OtpApplication”:

image.png

3. Package “com.example.otp.model”:

Nội dung class “Otp”:

image.png

Nội dung class “User”:

image.png

4. Package “com.example.otp.repository”:

Nội dung class “UserRepository”:

image.png

Nội dung class “OtpRepository”:

image.png

5. Package “com.example.otp.service”:

Nội dung class “IOtpService”:

image.png

Nội dung class “OtpService”:

image.png

6. Package “com.example.otp.controller”:

image.png

7. Application file:

image.png

Trong config tôi có enable SSL và HTTP/2, các bạn không cần làm điều này trong bài viết, tham khảo các bài viết ở trên tôi có hướng dẫn cách enable SSL và HTTP/2

Có 4 thuộc tính cần quan tâm là:

  • otp.expired.in: Thuộc tính này dùng để chỉ định thời gian sống cho Otp tính bằng phút

  • otp.max.length: Chỉ định độ dài tối đa của 1 mã otp, ở đây tôi chỉ định otp là 6 ký tự số

  • mail.trap.username: Đây là username trong mailtrap khi bạn tạo mới 1 inbox

  • mail.trap.password: Đây là password trong mailtrap khi bạn tạo mới 1 inbox

8. Nội dung script file:

image.png

Tôi có file “otp.html”, tôi khai báo đường dẫn cho script file:

image.png

Đường dẫn script file thì không phải cố định, tuỳ theo cấu trúc resources trên máy tính các bạn

9. Tạo phương thức tạo Otp code tự động:

Trong class “IOtpService”, tôi khai báo phương thức “generateOtp()” – “getOtpExpiredAt()” – “checkOtp()”:

image.png

Trong class “OtpService”, tôi lấy ra giá trị thuộc tính “otp.max.length” tôi đã khai báo trong application file

image.png

Tạo phương thức “generateOtp()”:

image.png

Tạo phương thức “getOtpExpiredAt()”:

image.png

Tạo phương thức “checkOtp()”:

image.png

10. Cấu hình gửi mail với MailTrap:

Để hiểu thêm về MailTrap, xem tại đây: https://help.mailtrap.io/article/40-faq#:~:text=Mailtrap is a fake SMTP,or flooding your own inboxes.

image.png

Sau khi chuẩn bị các bước trên, tiếp theo tôi hướng dẫn cấu hình để gửi mail với MailTrap:

Bước 1: Truy cập đường dẫn:https://mailtrap.io/

Bước 2: Tại trang chủ MailTrap -> đăng ký một tài khoản MailTrap, click button “Sign Up”:

image.png

Bước 3: Các bạn chọn loại đăng ký, ở đây tôi chọn “Use Google account”:

image.png

Bước 4: Sau khi tạo tài khoản thành công -> sẽ được điều hướng về trang dashboard của MailTrap, tại dashboard mục “Home” -> click button “Setup Inbox”:

image.png

Bước 5: Sau khi tạo xong “Inbox” -> tại mục “Sanbox > Inboxes”, tại tab “SMTP Settings” click “Show Credentials”:

image.png

Trong phần credentials chứa thông tin port – username – password nên các bạn cần giữ kỹ thông tin này

Tiếp theo, tôi cấu hình cho phần gửi mail Otp code:

Đầu tiên, tôi cần thêm 1 dependency “javax.mail” trong file “pom.xml”:

<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.5.0-b01</version>
</dependency>

Nội dung file pom:

image.png

Tôi khai báo thêm 2 thuộc tính là “mail.trap.username” và “mail.trap.password” trong application.yml:

image.png

Usename và password các bạn sẽ thấy trong mục “Show Credentials” trong dashboard Mailtrap

Tôi khai báo phương thức “sendOtp” trong class “IOtpService”:

image.png

Trong class “OtpService” lấy ra giá trị các thuộc tính username – password:

image.png

Phương thức “sendOtp” trong class “OtpService”:

image.png

Tôi cần cập nhật lại code cho phương thức “checkInfoUserLogin” trong “OtpController”, sau khi xác thực user có trong hệ thống -> generate new otp and gửi email đến user:

image.png

Sau khi gửi email thành công -> redirect -> otp page

Cập nhật lại phương thức “requestData()” trong script file:

image.png

Phương thức load otp page trong OtpController:

image.png

Tôi restart lại project và kiểm tra kịch bản user đăng nhập với tài khoản đúng -> otp được generate -> gửi mail với otp code đến user

image.png

=> Load thành công otp page

Kiểm tra database:

image.png

=> Thông tin otp được lưu thành công

Kiểm tra email gửi đến user, tôi vào trang dashboard của MailTrap. mục “Inbox”:

image.png

=> Mail được gửi thành công

Tiếp theo, tôi cần xử lý tại FE sau khi nhập xong otp -> tự động call api đến BE để xác thực OTP và nếu xác thực thành công -> chuyển đến dashboard page

Tại page “otp.html” tôi cập nhật lại 1 vài thứ:

image.png

Template tôi sử dụng được thiết kế đơn giản nên tương ứng cho mỗi field là 1 thẻ “<input />” nên để bắt sự kiện sau khi user nhập full otp tôi thêm sự kiên “onchange” trong mỗi fields vá gọi đến phương thức “checkOtpCode()” trong script file. Nên để nhanh các bạn chỉ cần sửa 1 field và clone ra

Nội dung phương thức “checkOtpCode” trong script file:

image.png

Nội dung phương thức “resendOtpCode” trong UserController:

image.png

Nội dung phương thức “resendOtpCode” trong script file:

image.png

Nội dung phương thức “getDashBoardPage” trong UserController:

image.png

Tôi restart lại project và kiểm tra kịch bản user đăng nhập với tài khoản xác thực thành công -> otp generated -> gửi mail otp và tôi nhập otp để kiểm tra:

image.png

image.png

image.png

=> Load dashboard page thành công

Tiếp theo, kiểm tra với kịch bản otp expired:

image.png

Kiểm tra với kịch bản resend otp:

Thêm sự kiện onclick trong button “Resend” trong otp page:

image.png

OTP đầu tiên:

image.png

Sau khi resend OTP:

image.png

Nguồn: viblo.asia

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *