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 :
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
}
2. User Repository:
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);
}
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
}
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;
}
}
@ 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());
}
}
}
Key Learning Points:
- Always encode passwords before storing.
- Use DTOs to handle request/response data.
- Implement proper validation and error handling.
- 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 .
Coming Up Next:
Adding JWT token authentication
Implementing role-based authorization
Top comments (0)