The Auth service handles user authentication, registration, and token management for the QeetMart platform. It issues JWT access tokens and refresh tokens.
Overview
Built with Spring Boot 3.3.8 and Spring Security, the auth service manages user credentials, authentication flows, session management, and audit logging.
The Auth service runs on port 4001 by default and uses PostgreSQL for data persistence.
Technology stack
Framework : Spring Boot 3.3.8
Language : Java 17
Database : PostgreSQL
Security : Spring Security + JWT (jjwt 0.12.6)
Key dependencies :
Spring Data JPA
Spring Security
Spring Boot Actuator
Micrometer Prometheus
Lombok
Configuration
Environment variables
Active Spring profile (dev, prod)
Database configuration
DB_HOST
string
default: "localhost"
PostgreSQL host
DB_NAME
string
default: "qeetmart_auth"
Database name
JWT configuration
JWT signing secret (minimum 32 bytes recommended)
JWT_ISSUER_URI
string
default: "http://localhost:4001"
JWT issuer URI
JWT_ACCESS_TOKEN_EXPIRATION
Access token expiration (e.g., 15m, 1h)
JWT_REFRESH_TOKEN_EXPIRATION
Refresh token expiration (e.g., 7d, 30d)
Security configuration
SECURITY_LOGIN_MAX_ATTEMPTS
Maximum failed login attempts before account lock
SECURITY_LOGIN_LOCK_DURATION_MINUTES
Account lock duration in minutes
SECURITY_LOGIN_REQUIRE_EMAIL_VERIFIED
Require email verification for login
SECURITY_LOGIN_SINGLE_SESSION_ENABLED
Allow only one active session per user
API endpoints
Register
POST /auth/register
Response
curl -X POST http://localhost:4001/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected] ",
"password": "SecurePass123!"
}'
Login
curl -X POST http://localhost:4001/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected] ",
"password": "SecurePass123!",
"deviceId": "mobile-device-123"
}'
Refresh token
POST /auth/refresh-token
Response
curl -X POST http://localhost:4001/auth/refresh-token \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'
Get current user
curl http://localhost:4001/auth/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Change password
POST /auth/change-password
Response
curl -X POST http://localhost:4001/auth/change-password \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"oldPassword": "OldPass123!",
"newPassword": "NewSecurePass456!"
}'
Logout
POST /auth/logout
Response
curl -X POST http://localhost:4001/auth/logout \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'
Logout all devices
POST /auth/logout-all
Response
curl -X POST http://localhost:4001/auth/logout-all \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Data models
UserCredential entity
@ Entity
@ Table ( name = "user_credentials" )
public class UserCredential {
@ Id
@ GeneratedValue ( strategy = GenerationType . IDENTITY )
private Long id ;
@ Column ( nullable = false , unique = true , length = 255 )
private String email ;
@ Column ( name = "password_hash" , nullable = false , length = 255 )
private String passwordHash ;
@ Enumerated ( EnumType . STRING )
@ Column ( nullable = false , length = 20 )
private Role role ; // CUSTOMER, ADMIN
@ Enumerated ( EnumType . STRING )
@ Column ( name = "account_status" , nullable = false , length = 20 )
private AccountStatus accountStatus ; // ACTIVE, LOCKED, SUSPENDED
@ Column ( name = "email_verified" , nullable = false )
private boolean emailVerified ;
@ Column ( name = "failed_login_attempts" , nullable = false )
private int failedLoginAttempts ;
@ Column ( name = "lock_until" )
private Instant lockUntil ;
@ Column ( name = "last_login_at" )
private Instant lastLoginAt ;
@ Column ( name = "created_at" , nullable = false , updatable = false )
private Instant createdAt ;
@ Column ( name = "updated_at" , nullable = false )
private Instant updatedAt ;
}
RefreshToken entity
The service stores refresh tokens in the database for session management and revocation.
Health check
GET /actuator/health
Response
curl http://localhost:4001/actuator/health
Metrics
Prometheus metrics are available at /actuator/prometheus.
Running the service
cd auth-service
mvn spring-boot:run
Security features
Password hashing : BCrypt with configurable strength
Account lockout : Automatic locking after failed login attempts
Token rotation : New refresh token issued on each refresh
Audit logging : All authentication events logged
Session management : Device-based session tracking
The JWT_SECRET must be kept secure and should be at least 32 bytes. Use the same secret across API Gateway and all services that verify tokens.
Dependencies
PostgreSQL : For user credentials and refresh tokens
No external service dependencies
Source code
Location: ~/workspace/source/micros/auth-service/
Key files:
src/main/java/com/qeetmart/auth/api/controller/AuthController.java - REST endpoints
src/main/java/com/qeetmart/auth/application/service/AuthApplicationService.java - Business logic
src/main/java/com/qeetmart/auth/domain/entity/UserCredential.java - User entity
src/main/resources/application.yml - Configuration