+2

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 UserController:

image.png

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

image.png

Sau khi resend OTP:

image.png

image.png

Nếu bạn nào muốn thông qua MailTrap gửi mail đến email thực sự thì có thể bỏ ra "9.99$" mua gói 1 tháng để kiểm tra, tôi đã mua gói này và kiểm tra để thấy email người nhận OTP là gmail của tôi có nhận được không:

Trước tiên, sau khi nâng cấp MailTrap, tại dashboard MailTrap cần thiết lập lại tại mục "Auto Forward", tại đây tôi thiết lập mục Email là email domain gmail của tôi, sau khi add email của tôi xong -> tôi restart lại project và thử đăng nhập để xem OTP có được forward về gmail của tôi không:

image.png

image.png

Kiểm tra gmail:

image.png

=> Đã forward thành công và mail gửi đến sẽ nằm trong mục mail rác, để thiết lập nâng cao hơn, các bạn có thể add domain tại dashboard MailTrap

Cuối cùng, bài viết này không nhằm mục đích quảng cáo cho MailTrap, tôi thấy MailTrap này khá hay nên tôi muốn thử nghiệm và chia sẻ đến các bạn.

Ngoài ra, bởi vì các bạn đã biết thông thường gửi mail chúng ta hay sử dụng SMTP gmail nhưng hiện tại từ ngày 30-05-2022 gmail đã disable tính năng "less secure" trong mục "Security" mà trước đó để có thể gửi mail dùng SMTP gmail chúng ta cần tính năng "less secure" để passed

image.png

Xem thêm thông tin về vấn đề này tại đây:

https://support.google.com/accounts/answer/6010255?hl=en#:~:text=Turn off "Less secure app access"&text=Go to the Less secure,Allow less secure apps off.

Còn đây là cách để các bạn vẫn có thể sử dụng SMTP gmail để gửi mail mà không cần "less secure":

image.png

Nguồn: https://stackoverflow.com/questions/72480275/is-there-a-work-around-google-disabling-less-secure-apps

Download source: http://megaurl.in/IqVf


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí