- vừa được xem lúc

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

0 0 56

Người đăng: Kien Pham

Theo Viblo Asia

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:

2. Package "com.example.otp.application":

Nội dung class "OtpApplication":

3. Package "com.example.otp.model":

Nội dung class "Otp":

Nội dung class "User":

4. Package "com.example.otp.repository":

Nội dung class "UserRepository":

Nội dung class "OtpRepository":

5. Package "com.example.otp.service":

Nội dung class "IOtpService":

Nội dung class "OtpService":

6. Package "com.example.otp.controller":

7. Application file:

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:

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

Đườ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()":

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

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

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

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

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.

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

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

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

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

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:

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

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

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

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

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:

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:

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

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

=> Load thành công otp page

Kiểm tra database:

=> 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":

=> 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ứ:

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:

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

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

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

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

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:

=> Load dashboard page thành công

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

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

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

OTP đầu tiên:

Sau khi resend OTP:

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:

Kiểm tra gmail:

=> Đã 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

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

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

Bình luận

Bài viết tương tự

- vừa được xem lúc

Elasticsearch là gì ?

. Lời nói đầu. Elasticsearch là gì .

0 0 35

- vừa được xem lúc

Backup và Restore Elasticsearch snapshot với AWS S3 trong Kubernetes

Ở công ty mình vừa có mấy task devops liên quan đến scaling, clustering Elasticsearch nên viết lại đề phòng sau này cần dùng. Có một task là chuyển dữ liệu từ single-node Elasticsearch cũ lên cluster mới.

0 0 50

- vừa được xem lúc

Reindex Elasticsearch data with zero downtime

Elasticsearch là một search engine tuyệt vời cho mọi dự án muốn áp dụng chức năng search cho sản phẩm của mình, với những tính năng như là near-realtime search, auto-complete, suggestion,.... Cùng với đó là lợi thế kiến trúc distributed search system, có thể dễ dàng scaling, failing handle. Khi muốn

0 0 40

- vừa được xem lúc

Fork you ElasticSearch! How Open Source Works

ElasticSearch recently dropped its open-source licensing strategy, prompting AWS to fork it. Learn how "Open Source" actually works and how companies profit from it.

0 0 48

- vừa được xem lúc

Tìm hiểu Text và Keyword trong Elasticsearch

Giới thiệu. Khi mình mới bắt đầu tìm hiểu về Elasticsearch mình không nghĩ rằng giữa kiểu dữ liệu Text và Keyword có sự khác nhau nhưng khi vào dự án thực tế mình mới nhận ra được sự khác biệt giữa 2

0 0 140

- vừa được xem lúc

Tìm hiểu và cài đặt Elasticsearch

Elasticsearch là gì. Elasticsearch cung cấp công cụ tìm tiếm và phân tích gần như là thời gian thực, áp dụng với mọi kiểu dữ liệu - văn bản có cấu trúc hoặc phi cấu trúc, số, thông tin địa lý.

0 0 113