Spring Boot 3 + JWT authentication + PostgreSQL REST API starter. Register, login, and access protected endpoints with Bearer tokens.
Built by the developer behind 32blog.com.
- Spring Boot 3.4 — Latest stable with Java 21
- JWT authentication — Stateless auth with jjwt 0.12
- BCrypt password hashing — Secure password storage
- PostgreSQL + JPA — Hibernate ORM with auto-schema generation
- Bean Validation — Request DTO validation with Jakarta Validation
- Role-based access — USER/ADMIN roles with method-level security
- Global error handling — Consistent JSON error responses
- H2 for tests — In-memory database for integration testing
- Java 21+
- Maven 3.9+
- PostgreSQL (or Docker)
docker run -d --name postgres \
-e POSTGRES_DB=mydb \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:16./mvnw spring-boot:runThe API starts at http://localhost:8080.
| Method | Path | Description |
|---|---|---|
POST |
/api/auth/register |
Register a new user |
POST |
/api/auth/login |
Login and receive JWT |
| Method | Path | Description |
|---|---|---|
GET |
/api/me |
Get current user info |
GET |
/api/health |
Health check |
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com", "password": "password123"}'Response:
{
"token": "eyJhbGciOiJIUzI1NiJ9...",
"email": "john@example.com",
"name": "John"
}curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "john@example.com", "password": "password123"}'curl http://localhost:8080/api/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..."src/main/java/com/example/api/
├── ApiApplication.java # Entry point
├── config/
│ ├── SecurityConfig.java # Spring Security + JWT filter chain
│ └── GlobalExceptionHandler.java # Error response handler
├── controller/
│ ├── AuthController.java # POST /register, /login
│ └── UserController.java # GET /me, /health
├── dto/
│ ├── RegisterRequest.java # Registration payload (validated)
│ ├── LoginRequest.java # Login payload (validated)
│ ├── AuthResponse.java # JWT + user info response
│ └── ErrorResponse.java # Standardized error format
├── entity/
│ └── User.java # JPA entity with USER/ADMIN roles
├── repository/
│ └── UserRepository.java # Spring Data JPA repository
├── security/
│ ├── JwtProvider.java # Token generation + validation
│ ├── JwtAuthFilter.java # OncePerRequestFilter for JWT
│ └── CustomUserDetailsService.java # UserDetailsService impl
└── service/
└── AuthService.java # Registration + login logic
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
jdbc:postgresql://localhost:5432/mydb |
PostgreSQL connection URL |
DATABASE_USERNAME |
postgres |
Database username |
DATABASE_PASSWORD |
postgres |
Database password |
JWT_SECRET |
(dev default) | HMAC-SHA256 signing key (min 256 bits) |
- Change
JWT_SECRETin production (min 32 characters) - Set
ddl-auto: validatein production (use Flyway/Liquibase for migrations) - Enable CORS if serving a frontend from a different origin
./mvnw testTests use H2 in-memory database (see application-test.yml).
| Component | Version |
|---|---|
| Spring Boot | 3.4.3 |
| Java | 21 |
| jjwt | 0.12.6 |
| PostgreSQL | 16 |
| H2 (test) | latest |