{"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"],"_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}]}}