DEV Community

Eliud Githuku
Eliud Githuku

Posted on

Implementing Email Code Verification in Java Spring Boot

Introduction

Email verification is a critical component in many applications, especially during user registration, password recovery, and other security-sensitive processes. Verifying a user's email ensures that they are legitimate and helps protect against fraudulent activities. In this blog, we will walk through how to implement email code verification in a Spring Boot application. We will explore use cases, the structure of the verification code (numbers, letters, or a combination), and how to test the implementation to ensure reliability.

Prerequisites

Before we dive into the implementation, make sure you have the following:

  1. Basic knowledge of Java and Spring Boot.
  2. A working Spring Boot project set up with the following dependencies:
    • Spring Web
    • Spring Security
    • Spring Data JPA
    • Thymeleaf (optional for email templates)
    • JavaMailSender for sending emails
  3. An SMTP server for sending emails (e.g., Gmail SMTP).
  4. Basic understanding of unit and integration testing in Spring Boot.

Step 1: Setting Up the Project

Start by creating a new Spring Boot project or using an existing one. Add the necessary dependencies in your pom.xml or build.gradle file.

For Maven:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
</dependencies>
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Verification Code Generator

A good verification code should be unique, unpredictable, and secure. You can choose to generate a code consisting of numbers, letters, or a combination of both. Here's a simple implementation using a random combination of letters and numbers:

import java.security.SecureRandom;

public class VerificationCodeGenerator {
    private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    private static final int CODE_LENGTH = 6;
    private static final SecureRandom random = new SecureRandom();

    public static String generateVerificationCode() {
        StringBuilder code = new StringBuilder(CODE_LENGTH);
        for (int i = 0; i < CODE_LENGTH; i++) {
            code.append(CHARACTERS.charAt(random.nextInt(CHARACTERS.length())));
        }
        return code.toString();
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Send the Verification Email

Next, you need to send the verification code to the user's email. Use the JavaMailSender to achieve this. Create a service that will handle email sending:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
public class EmailService {

    @Autowired
    private JavaMailSender mailSender;

    public void sendVerificationEmail(String toEmail, String verificationCode) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(toEmail);
        message.setSubject("Email Verification Code");
        message.setText("Your verification code is: " + verificationCode);
        mailSender.send(message);
    }
}

Enter fullscreen mode Exit fullscreen mode

Step 4: Store the Verification Code

Store the verification code in the database associated with the user. This helps in verifying the code later when the user submits it.

import javax.persistence.*;

@Entity
public class UserVerification {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String email;

    @Column(nullable = false)
    private String verificationCode;

    // Getters and Setters
}

Enter fullscreen mode Exit fullscreen mode

Create a repository interface for storing the verification data:

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserVerificationRepository extends JpaRepository<UserVerification, Long> {
    UserVerification findByEmail(String email);
}

Enter fullscreen mode Exit fullscreen mode

Step 5: Verify the Code

When the user submits the verification code, you need to validate it against the code stored in the database.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class VerificationService {

    @Autowired
    private UserVerificationRepository verificationRepository;

    public boolean verifyCode(String email, String code) {
        UserVerification userVerification = verificationRepository.findByEmail(email);
        if (userVerification != null && userVerification.getVerificationCode().equals(code)) {
            // Verification successful
            return true;
        }
        // Verification failed
        return false;
    }
}

Enter fullscreen mode Exit fullscreen mode

Step 6: Testing the Implementation

It's essential to test your implementation to ensure that it works as expected. Create unit tests to validate the verification code generation and the email sending process. You can also write integration tests to ensure that the entire flow works smoothly.

Here’s an example of a simple test for the code generator:

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.junit.jupiter.api.Test;

public class VerificationCodeGeneratorTest {

    @Test
    public void testGenerateVerificationCode() {
        String code = VerificationCodeGenerator.generateVerificationCode();
        assertNotNull(code);
        assertEquals(6, code.length());
    }
}

Enter fullscreen mode Exit fullscreen mode

For testing the email service, you might want to use mocks:

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.SimpleMailMessage;

public class EmailServiceTest {

    @Test
    public void testSendVerificationEmail() {
        JavaMailSender mailSender = mock(JavaMailSender.class);
        EmailService emailService = new EmailService();
        emailService.mailSender = mailSender;

        String email = "user@example.com";
        String code = "ABC123";

        emailService.sendVerificationEmail(email, code);

        verify(mailSender, times(1)).send(any(SimpleMailMessage.class));
    }
}

Enter fullscreen mode Exit fullscreen mode

Conclusion

Implementing email code verification in your Spring Boot application is a crucial step to secure user authentication and sensitive processes. By following the steps outlined in this blog, you can create a robust and reliable email verification system. Don't forget to test your implementation thoroughly to ensure it performs as expected under different scenarios. Whether you choose to use numeric codes, alphabetic characters, or a combination of both, the key is to make the verification process secure and user-friendly.

Top comments (0)