{"id":473,"date":"2024-07-23T17:52:31","date_gmt":"2024-07-23T17:52:31","guid":{"rendered":"https:\/\/www.kindsonthegenius.com\/spring-boot\/?p=473"},"modified":"2024-11-03T10:18:28","modified_gmt":"2024-11-03T10:18:28","slug":"springboot-email-verification","status":"publish","type":"post","link":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/","title":{"rendered":"SpringBoot &#8211; Email Verification (Code With Me)"},"content":{"rendered":"<p>In this tutorial, you will learn how to enable email verification on Spring boot application.<\/p>\n<figure id=\"attachment_480\" aria-describedby=\"caption-attachment-480\" style=\"width: 730px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-scaled.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-480 size-large\" src=\"https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-730x1024.jpg\" alt=\"Email Verification Workflow in SpringBoot\" width=\"730\" height=\"1024\" srcset=\"https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-730x1024.jpg 730w, https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-214x300.jpg 214w, https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-768x1078.jpg 768w, https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-1095x1536.jpg 1095w, https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-1460x2048.jpg 1460w, https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-scaled.jpg 1825w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/a><figcaption id=\"caption-attachment-480\" class=\"wp-caption-text\">Email Verification Workflow in SpringBoot<\/figcaption><\/figure>\n<p><strong>The Flow<\/strong><\/p>\n<ol>\n<li>User fills and submits registration form<\/li>\n<li>UserService receives and saves the user information with accountVerified set to false<\/li>\n<li>UserService creates and saves a new SecureToken<\/li>\n<li>UserService sends a verification email to user along with a link having the secure token<\/li>\n<li>The user receives the email and clicks on the verification link<\/li>\n<li>UserServices receives the request<\/li>\n<li>UserService extracts the token<\/li>\n<li>Check if the token is valid (exists)<\/li>\n<li>Verifies user by setting the accountVerified field to True<\/li>\n<li>Removes the secure token<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>Step1 &#8211; Setup Your Dependencies<\/strong><\/p>\n<ol>\n<li>Add the springboot-starter-mail dependency<\/li>\n<li>Add the <em>commons-lang3 dependency<\/em> (we need the BooleanUtils module from here)<\/li>\n<li>We would also need <em>com.sun.xml.messaging.saaj<\/em><\/li>\n<li>Also make sure you have the MySQL dependency<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>Step 2 &#8211; Create the SecureToken model<\/strong><\/p>\n<p>Create the SecureToken model in the security\/models package.<\/p>\n<p>These SecureToken model will have the following fields<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">    <span style=\"color: #008800; font-weight: bold;\">private<\/span> Long id<span style=\"color: #333333;\">;<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> String token<span style=\"color: #333333;\">;<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> LocalDateTime expiredAt<span style=\"color: #333333;\">;<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> User user<span style=\"color: #333333;\">;<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Step 3 &#8211; Update the User model to include these fields<\/strong><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>email<\/li>\n<li>accountVerified (boolean)<\/li>\n<li>loginDisabled (boolean)<\/li>\n<li>tokens (set of SecureToken)<\/li>\n<li>setter for loginDisabled<\/li>\n<li>make the User model extend Auditable<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>Step 4 &#8211; Create EmailContext<\/strong><\/p>\n<p>Create the mailing package and inside it:<\/p>\n<ul>\n<li>create the <em>AbstractEmailContext<\/em> ( an abstract class whose constructor returns a hashmap of email properties)<\/li>\n<\/ul>\n<p>It would have the following fields:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">    <span style=\"color: #008800; font-weight: bold;\">private<\/span> String from<span style=\"color: #333333;\">;<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> String to<span style=\"color: #333333;\">;<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> String subject<span style=\"color: #333333;\">;<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> String email<span style=\"color: #333333;\">;<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> String templateLocation<span style=\"color: #333333;\">;<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> Map<span style=\"color: #333333;\">&lt;<\/span>String<span style=\"color: #333333;\">,<\/span> Object<span style=\"color: #333333;\">&gt;<\/span> context<span style=\"color: #333333;\">;<\/span>\r\n<\/pre>\n<p>In addition to the getters and the setters, this class would have :<\/p>\n<ul>\n<li>a put() method the puts item into the context<\/li>\n<li>an init() method to with an empty body (for performing some initial configuration)<\/li>\n<li>a constructor that initializes an empty context<\/li>\n<\/ul>\n<p>these are give below:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #0066bb; font-weight: bold;\">AbstractEmailContext<\/span><span style=\"color: #333333;\">()<\/span> <span style=\"color: #333333;\">{<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">this<\/span><span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">context<\/span> <span style=\"color: #333333;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> HashMap<span style=\"color: #333333;\">&lt;&gt;();<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #333333;\">&lt;<\/span>T<span style=\"color: #333333;\">&gt;<\/span> <span style=\"color: #333399; font-weight: bold;\">void<\/span> init<span style=\"color: #333333;\">(<\/span>T context<span style=\"color: #333333;\">){<\/span>\r\n    <span style=\"color: #888888;\">\/\/we can do any common configuration setup here<\/span>\r\n    <span style=\"color: #888888;\">\/\/ like setting up some base URL and context<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> Object <span style=\"color: #0066bb; font-weight: bold;\">put<\/span><span style=\"color: #333333;\">(<\/span>String key<span style=\"color: #333333;\">,<\/span> Object value<span style=\"color: #333333;\">)<\/span> <span style=\"color: #333333;\">{<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">return<\/span> key <span style=\"color: #333333;\">==<\/span><span style=\"color: #008800; font-weight: bold;\">null<\/span> <span style=\"color: #333333;\">?<\/span> <span style=\"color: #008800; font-weight: bold;\">null<\/span> <span style=\"color: #333333;\">:<\/span> <span style=\"color: #008800; font-weight: bold;\">this<\/span><span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">context<\/span><span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">put<\/span><span style=\"color: #333333;\">(<\/span>key<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">intern<\/span><span style=\"color: #333333;\">(),<\/span>value<span style=\"color: #333333;\">);<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Step 5 &#8211; Create the AccountVerificationEmailContext<\/strong><\/p>\n<ul>\n<li>create the AccountVerificationEmailContext (extends the AbstractEmailContext)<\/li>\n<\/ul>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">private<\/span> String token<span style=\"color: #333333;\">;<\/span>\r\n\r\n<span style=\"color: #555555; font-weight: bold;\">@Override<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #333333;\">&lt;<\/span>T<span style=\"color: #333333;\">&gt;<\/span> <span style=\"color: #333399; font-weight: bold;\">void<\/span> init<span style=\"color: #333333;\">(<\/span>T context<span style=\"color: #333333;\">){<\/span>\r\n    User user <span style=\"color: #333333;\">=<\/span> <span style=\"color: #333333;\">(<\/span>User<span style=\"color: #333333;\">)<\/span> context<span style=\"color: #333333;\">;<\/span>\r\n    put<span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"firstName\"<\/span><span style=\"color: #333333;\">,<\/span> user<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getFirstname<\/span><span style=\"color: #333333;\">());<\/span>\r\n    setTemplateLocation<span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"mailing\/email-verification\"<\/span><span style=\"color: #333333;\">);<\/span>\r\n    setSubject<span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"Complete your registration\"<\/span><span style=\"color: #333333;\">);<\/span>\r\n    setFrom<span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"no-reply@kttpro.com\"<\/span><span style=\"color: #333333;\">);<\/span>\r\n    setTo<span style=\"color: #333333;\">(<\/span>user<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getEmail<\/span><span style=\"color: #333333;\">());<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #333399; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">setToken<\/span><span style=\"color: #333333;\">(<\/span>String token<span style=\"color: #333333;\">)<\/span> <span style=\"color: #333333;\">{<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">this<\/span><span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">token<\/span> <span style=\"color: #333333;\">=<\/span> token<span style=\"color: #333333;\">;<\/span>\r\n    put<span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"token\"<\/span><span style=\"color: #333333;\">,<\/span> token<span style=\"color: #333333;\">);<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #333399; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">buildVerificationUrl<\/span><span style=\"color: #333333;\">(<\/span><span style=\"color: #008800; font-weight: bold;\">final<\/span> String baseURL<span style=\"color: #333333;\">,<\/span> <span style=\"color: #008800; font-weight: bold;\">final<\/span> String token<span style=\"color: #333333;\">){<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">final<\/span> String url<span style=\"color: #333333;\">=<\/span> UriComponentsBuilder<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">fromHttpUrl<\/span><span style=\"color: #333333;\">(<\/span>baseURL<span style=\"color: #333333;\">)<\/span>\r\n            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">path<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"\/register\/verify\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">queryParam<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"token\"<\/span><span style=\"color: #333333;\">,<\/span> token<span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">toUriString<\/span><span style=\"color: #333333;\">();<\/span>\r\n    put<span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"verificationURL\"<\/span><span style=\"color: #333333;\">,<\/span> url<span style=\"color: #333333;\">);<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Step 7 &#8211; Create and implement the EmailService<\/strong><\/p>\n<p>Also inside the mailing package:<\/p>\n<ul>\n<li><em>EmailService<\/em> interface (declares <strong>sendMail()<\/strong> method)<\/li>\n<\/ul>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #333399; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">sendMail<\/span><span style=\"color: #333333;\">(<\/span><span style=\"color: #008800; font-weight: bold;\">final<\/span> AbstractEmailContext email<span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">throws<\/span> javax<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">mail<\/span><span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">MessagingException<\/span><span style=\"color: #333333;\">;<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<ul>\n<li><em>DefaultEmailService<\/em> (implements the EmailService and\u00a0 the <em>sendMail()<\/em> method). The body of the<em> sendMail()<\/em> function is given below:<\/li>\n<\/ul>\n<pre style=\"margin: 0; line-height: 125%;\">MimeMessage message <span style=\"color: #333333;\">=<\/span> emailSender<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">createMimeMessage<\/span><span style=\"color: #333333;\">();<\/span>\r\nMimeMessageHelper mimeMessageHelper <span style=\"color: #333333;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> MimeMessageHelper<span style=\"color: #333333;\">(<\/span>message<span style=\"color: #333333;\">,<\/span>\r\n        MimeMessageHelper<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">MULTIPART_MODE_MIXED_RELATED<\/span><span style=\"color: #333333;\">,<\/span>\r\n        StandardCharsets<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">UTF_8<\/span><span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">name<\/span><span style=\"color: #333333;\">());<\/span>\r\nContext context <span style=\"color: #333333;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> Context<span style=\"color: #333333;\">();<\/span>\r\ncontext<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setVariables<\/span><span style=\"color: #333333;\">(<\/span>email<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getContext<\/span><span style=\"color: #333333;\">());<\/span>\r\nString emailContent <span style=\"color: #333333;\">=<\/span> templateEngine<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">process<\/span><span style=\"color: #333333;\">(<\/span>email<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getTemplateLocation<\/span><span style=\"color: #333333;\">(),<\/span> context<span style=\"color: #333333;\">);<\/span>\r\n\r\nmimeMessageHelper<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setTo<\/span><span style=\"color: #333333;\">(<\/span>email<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getTo<\/span><span style=\"color: #333333;\">());<\/span>\r\nmimeMessageHelper<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setSubject<\/span><span style=\"color: #333333;\">(<\/span>email<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getSubject<\/span><span style=\"color: #333333;\">());<\/span>\r\nmimeMessageHelper<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setFrom<\/span><span style=\"color: #333333;\">(<\/span>email<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getFrom<\/span><span style=\"color: #333333;\">());<\/span>\r\nmimeMessageHelper<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setText<\/span><span style=\"color: #333333;\">(<\/span>emailContent<span style=\"color: #333333;\">,<\/span> <span style=\"color: #008800; font-weight: bold;\">true<\/span><span style=\"color: #333333;\">);<\/span>\r\nemailSender<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">send<\/span><span style=\"color: #333333;\">(<\/span>message<span style=\"color: #333333;\">);<\/span>\r\n<\/pre>\n<p>You will also need to\u00a0 need to:<\/p>\n<ul>\n<li>wire in the <em>JavaMailSender<\/em> and <em>SpringTemplateEngine<\/em><\/li>\n<li>add the <span style=\"background-color: #eeeeee; font-family: 'Courier 10 Pitch', Courier, monospace; font-size: 0.9375rem;\">thymeleaf-extras-springsecurity5<\/span> and the <span style=\"background-color: #eeeeee; font-family: 'Courier 10 Pitch', Courier, monospace; font-size: 0.9375rem;\">spring-boot-starter-thymeleaf<\/span>\u00a0dependencies<\/li>\n<\/ul>\n<p>The context used here is coming from <em>org.thymeleaf.context<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 8 &#8211; Create the SecureTokenRepository and Service<\/strong><\/p>\n<ol>\n<li>Setup the <em>SecureTokenRepository<\/em> which should contain <em>findByToken()<\/em> and <em>removeToken()<\/em> methods<\/li>\n<li>Create the <em>SecureTokenService<\/em> interface which would expose the CRUD SecureToken operations<\/li>\n<li>Create the <em>DefaultSecureTokenService<\/em> (implements the <em>SecureTokenService<\/em> and implements the methods)<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>Step 9 &#8211; Add the mailing properties to the application.properties file<\/strong><\/p>\n<ul>\n<li>Create the app using a Google account and obtain the mailing properties. Follow these steps:\n<ul>\n<li>Open Gmail<\/li>\n<li>Click your profile avatar at the upper right<\/li>\n<li>Select &#8220;Manager Your Google Account&#8221;<\/li>\n<li>Click on Security<\/li>\n<li>2-Step verification<\/li>\n<li>Scroll down and select App Passwords (if you don&#8217;t see App Passwords, scroll down and under <em>Looking for Something Else<\/em>, select <em>Search Google Account<\/em>. Type <em>App Passwords<\/em> and then select it)<\/li>\n<li>Create an new app and then get the credentials<\/li>\n<\/ul>\n<\/li>\n<li>Add the mailing values to the properties file<\/li>\n<li>Remember to add the <strong>site.base.url.https<\/strong> property with the correct port.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><strong>Step 10 &#8211; Implement the <em>sendRegistrationConfirmationEmail<\/em> Function<\/strong><\/p>\n<ol>\n<li>We would need to write a few custom exceptions. We put them an an <em>exception<\/em> package.\n<ul>\n<li>InvalidTokenException<\/li>\n<li>UnkownIdentifierException<\/li>\n<li>UserAlreadyExistsException<\/li>\n<\/ul>\n<\/li>\n<li>Update the UserRepository to include the <em>findByEmail()<\/em> method<\/li>\n<li>Update the UserService:\n<ul>\n<li>Write the <em>checkIfUserExists()<\/em> function<\/li>\n<li>Rename the <em>save()<\/em> method to <em>register()<\/em><\/li>\n<li>Write the <em>sendRegistrationConfirmationEmail()<\/em> method<\/li>\n<li>The register method should first check if user exists, save the user and then call the <em>sendRegistrationConfirmationEmail()<\/em> method<\/li>\n<li>Update the UserController: modify the <em>addNew()<\/em> method to call the service&#8217;s <em>register()<\/em> method and send a success message<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>Step 11 &#8211; Create Html templates and Update the RegistrationPage<\/strong><\/p>\n<ol>\n<li>Create the mailing directory in the templates folder and create the<strong> email-verification.html<\/strong> template. <a href=\"https:\/\/raw.githubusercontent.com\/KindsonTheGenius\/fleetms-v2\/master\/src\/main\/resources\/templates\/mailing\/email-verification.html\" target=\"_blank\" rel=\"noopener\">Get it here.<\/a><\/li>\n<li>Create the <em>registrationSuccessful<\/em> template inside the security folder. <a href=\"https:\/\/raw.githubusercontent.com\/KindsonTheGenius\/fleetms-v2\/refs\/heads\/master\/src\/main\/resources\/templates\/security\/registrationSuccessful.html\" target=\"_blank\" rel=\"noopener\">Get it here<\/a> (this is only for FleetMS and does not apply to InventoryMS).<\/li>\n<li>Modify the Registration template form to include both username and email<\/li>\n<li>Modify the <em>password\/confirmPassword<\/em> fields so that we can check that the two does not match using script<\/li>\n<li>Add the script for checking password.<\/li>\n<\/ol>\n<p><strong>For InventoryMS<\/strong>: we would create the success pages in the <em>React UI app<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 12 &#8211; Update the ApplicationSecurityConfig<\/strong><\/p>\n<ol>\n<li>Update the ApplicationSecurityConfig to allow access to the <em><strong>\/usersAddNew<\/strong><\/em> route<\/li>\n<li>Add the <em><strong>\/register\/verify<\/strong><\/em> url to the ApplicationSecurityConfig file<\/li>\n<li><strong>Test(5)<\/strong> &#8211; Test the Verification Email functionality<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>Step 13 &#8211; Setup the \/verify URL<\/strong><\/p>\n<ol>\n<li>Write the <em>verifyUser()<\/em> method which takes a token and validates that token exists and it is the user&#8217;s token. It\n<ul>\n<li>tests for empty token<\/li>\n<li>checks for empty user<\/li>\n<\/ul>\n<\/li>\n<li>Create a registrationController in the controllers package and provide the method for <em><strong>\/verify<\/strong><\/em> url. This method does the following:\n<ul>\n<li>checks for empty token<\/li>\n<li>calls the userService&#8217;<em> verifyUser()<\/em> method and catches any exception<\/li>\n<li>redirects user to login page with a success message<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>Step 14 &#8211; Update UserPrincipal to use accountVerified and Create Messages<\/strong><\/p>\n<ol>\n<li>Update the isEnabled method of the UserPrincipal to return <strong>user.isAccountVerified()<\/strong><\/li>\n<li>Create the message bundle<\/li>\n<li><strong>Test(6)<\/strong> &#8211; Test the <em>\/verify<\/em> function<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Happy coding!!!<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you will learn how to enable email verification on Spring boot application. The Flow User fills and submits registration form UserService receives &hellip; <!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[2],"tags":[63],"class_list":["post-473","post","type-post","status-publish","format-standard","hentry","category-spring-boot-tutorials","tag-email-verification"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>SpringBoot - Email Verification (Code With Me) - Learn Spring Boot<\/title>\n<meta name=\"description\" content=\"In this tutorial, you will learn how to set up SpringBoot email verification and send verification email to newly registered user\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SpringBoot - Email Verification (Code With Me) - Learn Spring Boot\" \/>\n<meta property=\"og:description\" content=\"In this tutorial, you will learn how to set up SpringBoot email verification and send verification email to newly registered user\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/\" \/>\n<meta property=\"og:site_name\" content=\"Learn Spring Boot\" \/>\n<meta property=\"article:published_time\" content=\"2024-07-23T17:52:31+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-11-03T10:18:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-730x1024.jpg\" \/>\n<meta name=\"author\" content=\"kindsonthegenius\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"kindsonthegenius\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/\"},\"author\":{\"name\":\"kindsonthegenius\",\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/#\\\/schema\\\/person\\\/00180918216a22ec4062a3528fedcb13\"},\"headline\":\"SpringBoot &#8211; Email Verification (Code With Me)\",\"datePublished\":\"2024-07-23T17:52:31+00:00\",\"dateModified\":\"2024-11-03T10:18:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/\"},\"wordCount\":838,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/wp-content\\\/uploads\\\/2024\\\/07\\\/Email-Verification-Workflow-in-SpringBoot-730x1024.jpg\",\"keywords\":[\"Email Verification\"],\"articleSection\":[\"Spring Boot Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/\",\"url\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/\",\"name\":\"SpringBoot - Email Verification (Code With Me) - Learn Spring Boot\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/wp-content\\\/uploads\\\/2024\\\/07\\\/Email-Verification-Workflow-in-SpringBoot-730x1024.jpg\",\"datePublished\":\"2024-07-23T17:52:31+00:00\",\"dateModified\":\"2024-11-03T10:18:28+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/#\\\/schema\\\/person\\\/00180918216a22ec4062a3528fedcb13\"},\"description\":\"In this tutorial, you will learn how to set up SpringBoot email verification and send verification email to newly registered user\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/#primaryimage\",\"url\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/wp-content\\\/uploads\\\/2024\\\/07\\\/Email-Verification-Workflow-in-SpringBoot-scaled.jpg\",\"contentUrl\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/wp-content\\\/uploads\\\/2024\\\/07\\\/Email-Verification-Workflow-in-SpringBoot-scaled.jpg\",\"width\":1825,\"height\":2560,\"caption\":\"Email Verification Workflow in SpringBoot\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/springboot-email-verification\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SpringBoot &#8211; Email Verification (Code With Me)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/#website\",\"url\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/\",\"name\":\"Learn Spring Boot\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/#\\\/schema\\\/person\\\/00180918216a22ec4062a3528fedcb13\",\"name\":\"kindsonthegenius\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b9d710de456c3d85e5614c3a6992fa3d527425e2ab32b8bd5d85bfbaa235004b?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b9d710de456c3d85e5614c3a6992fa3d527425e2ab32b8bd5d85bfbaa235004b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b9d710de456c3d85e5614c3a6992fa3d527425e2ab32b8bd5d85bfbaa235004b?s=96&d=mm&r=g\",\"caption\":\"kindsonthegenius\"},\"url\":\"https:\\\/\\\/kindsonthegenius.com\\\/spring-boot\\\/author\\\/kindsonthegenius-3\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"SpringBoot - Email Verification (Code With Me) - Learn Spring Boot","description":"In this tutorial, you will learn how to set up SpringBoot email verification and send verification email to newly registered user","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/","og_locale":"en_US","og_type":"article","og_title":"SpringBoot - Email Verification (Code With Me) - Learn Spring Boot","og_description":"In this tutorial, you will learn how to set up SpringBoot email verification and send verification email to newly registered user","og_url":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/","og_site_name":"Learn Spring Boot","article_published_time":"2024-07-23T17:52:31+00:00","article_modified_time":"2024-11-03T10:18:28+00:00","og_image":[{"url":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-730x1024.jpg","type":"","width":"","height":""}],"author":"kindsonthegenius","twitter_card":"summary_large_image","twitter_misc":{"Written by":"kindsonthegenius","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/#article","isPartOf":{"@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/"},"author":{"name":"kindsonthegenius","@id":"https:\/\/kindsonthegenius.com\/spring-boot\/#\/schema\/person\/00180918216a22ec4062a3528fedcb13"},"headline":"SpringBoot &#8211; Email Verification (Code With Me)","datePublished":"2024-07-23T17:52:31+00:00","dateModified":"2024-11-03T10:18:28+00:00","mainEntityOfPage":{"@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/"},"wordCount":838,"commentCount":0,"image":{"@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/#primaryimage"},"thumbnailUrl":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-730x1024.jpg","keywords":["Email Verification"],"articleSection":["Spring Boot Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/","url":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/","name":"SpringBoot - Email Verification (Code With Me) - Learn Spring Boot","isPartOf":{"@id":"https:\/\/kindsonthegenius.com\/spring-boot\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/#primaryimage"},"image":{"@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/#primaryimage"},"thumbnailUrl":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-730x1024.jpg","datePublished":"2024-07-23T17:52:31+00:00","dateModified":"2024-11-03T10:18:28+00:00","author":{"@id":"https:\/\/kindsonthegenius.com\/spring-boot\/#\/schema\/person\/00180918216a22ec4062a3528fedcb13"},"description":"In this tutorial, you will learn how to set up SpringBoot email verification and send verification email to newly registered user","breadcrumb":{"@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/#primaryimage","url":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-scaled.jpg","contentUrl":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-content\/uploads\/2024\/07\/Email-Verification-Workflow-in-SpringBoot-scaled.jpg","width":1825,"height":2560,"caption":"Email Verification Workflow in SpringBoot"},{"@type":"BreadcrumbList","@id":"https:\/\/kindsonthegenius.com\/spring-boot\/springboot-email-verification\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kindsonthegenius.com\/spring-boot\/"},{"@type":"ListItem","position":2,"name":"SpringBoot &#8211; Email Verification (Code With Me)"}]},{"@type":"WebSite","@id":"https:\/\/kindsonthegenius.com\/spring-boot\/#website","url":"https:\/\/kindsonthegenius.com\/spring-boot\/","name":"Learn Spring Boot","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kindsonthegenius.com\/spring-boot\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/kindsonthegenius.com\/spring-boot\/#\/schema\/person\/00180918216a22ec4062a3528fedcb13","name":"kindsonthegenius","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b9d710de456c3d85e5614c3a6992fa3d527425e2ab32b8bd5d85bfbaa235004b?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b9d710de456c3d85e5614c3a6992fa3d527425e2ab32b8bd5d85bfbaa235004b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b9d710de456c3d85e5614c3a6992fa3d527425e2ab32b8bd5d85bfbaa235004b?s=96&d=mm&r=g","caption":"kindsonthegenius"},"url":"https:\/\/kindsonthegenius.com\/spring-boot\/author\/kindsonthegenius-3\/"}]}},"_links":{"self":[{"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/posts\/473","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/comments?post=473"}],"version-history":[{"count":23,"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/posts\/473\/revisions"}],"predecessor-version":[{"id":530,"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/posts\/473\/revisions\/530"}],"wp:attachment":[{"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/media?parent=473"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/categories?post=473"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/spring-boot\/wp-json\/wp\/v2\/tags?post=473"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}