DEV Community

Ajinkya. Shivpure
Ajinkya. Shivpure

Posted on

Building User Authentication in Spring Boot: From Signup to Login

After setting up our first Spring Boot project (check my previous post!), let's add user authentication. I'll show you how I implemented signup and login functionality using Spring Boot's layered architecture.

Project Structure:

Now , as a beginner even keeping a proper structure for your project can be difficult . create proper packages and classes. here is the project structure you should use :

Intelli J

structure

1.The User Entity:

(we created this earlier as well ):
this user entity class stores all the attributes of a user like name , email and password .

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(unique = true, nullable = false)
    private String email;

    @Column(nullable = false)
    private String password;  // Will be stored encoded
}
Enter fullscreen mode Exit fullscreen mode

2. User Repository:

layers

Refer the above diagram for better clarification . the database layer is basically the repository . here , the user repository is responsible for connecting with our my sql database . it has complete access to the user table . we are using the JpaRepository for some built in features .

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);
    Boolean existsByEmail(String email);
}
Enter fullscreen mode Exit fullscreen mode

3. DTOs - for request and response

we use this for convenience. you will understand as you proceed.

public class SignupRequest {
    private String name;
    private String email;
    private String password;
    // getters, setters
}

public class LoginRequest {
    private String email;
    private String password;
    // getters, setters
}
Enter fullscreen mode Exit fullscreen mode

4. Auth Service :

the work of the service layer is to receive request from api layer , process that request. the api layer does not communicate with the data access layers directly . see the api controller layer further below , it just contains certain endpoints then in each method , it calls the methods in service layer .
we create a repository object in services and service object in controllers . that's how it works!
I am not explaining much from this code , most of this is basic to moderate Java .

@Service
@Transactional
public class AuthService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    public User signup(SignupRequest request) {
        // Check if user exists
        if (userRepository.existsByEmail(request.getEmail())) {
            throw new RuntimeException("Email already registered");
        }

        // Create new user
        User user = new User();
        user.setName(request.getName());
        user.setEmail(request.getEmail());
        user.setPassword(passwordEncoder.encode(request.getPassword()));

        return userRepository.save(user);
    }

    public User login(LoginRequest request) {
        User user = userRepository.findByEmail(request.getEmail())
            .orElseThrow(() -> new RuntimeException("User not found"));

        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new RuntimeException("Invalid password");
        }

        return user;
    }
}
Enter fullscreen mode Exit fullscreen mode

@ Autowired makes the work easier , instead of initiating the object in constructor just use the annotation @autowired , it automatically tells springboot what we need .

5. Auth Controller :

let me explain the important key components :
@RequestMapping: it tells that all the requests will be sent on "/api/auth" . you can customise it . the default path for requests is
http://localhost:8080/api/auth . by requests , I mean the ones from frontend .
@PostMapping:
it tells that the tor of request is the post request , that is some data is going to be submitted to the repository . now , the complete path becomes
http://localhost:8080/api/auth/signup for sign up and so on

@RestController
@RequestMapping("/api/auth")
public class AuthController {
    @Autowired
    private AuthService authService;

    @PostMapping("/signup")
    public ResponseEntity<?> signup(@RequestBody SignupRequest request) {
        try {
            User user = authService.signup(request);
            return ResponseEntity.ok("User registered successfully");
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest request) {
        try {
            User user = authService.login(request);
            return ResponseEntity.ok("Login successful");
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Key Learning Points:

  1. Always encode passwords before storing.
  2. Use DTOs to handle request/response data.
  3. Implement proper validation and error handling.
  4. Follow separation of concerns (Controller → Service → Repository).

Now , we need to test these apis. I use postman for this purpose . I will recommend for all of you to go with it .

PostMan testing:

the following image should be enough .

postman


Coming Up Next:

  • Adding JWT token authentication

  • Implementing role-based authorization


springboot #java #security #authentication #webdev

Top comments (0)