API Sessions - Spring Boot REST API with JWT Authentication
A complete CRUD REST API implementation using Spring Boot 4.x with JWT authentication, H2 database, and Spring Security session management.
Features
- JWT Authentication: Secure API endpoints with JSON Web Tokens
- Spring Security Integration: JWT tokens linked to Spring Security sessions
- CRUD Operations: Full Create, Read, Update, Delete operations for products
- H2 Database: In-memory database with auto-initialization
- RESTful API: Clean REST architecture with proper HTTP methods
- Data Initialization: Sample data loaded on startup for testing
- Comprehensive Testing: Shell scripts for API testing
Technologies Used
- Spring Boot 4.1.0-M1 (Java 21)
- Spring Security - Authentication and authorization
- Spring Data JPA - Database access
- H2 Database - In-memory database
- JWT (JJWT 0.12.6) - Token generation and validation
- Lombok - Reduce boilerplate code
- Maven - Dependency management
Project Structure
src/main/java/com/manalejandro/api_sessions/
├── config/
│ ├── SecurityConfig.java # Spring Security configuration
│ └── DataInitializer.java # Database initialization
├── controller/
│ ├── AuthController.java # Authentication endpoints
│ └── ProductController.java # Product CRUD endpoints
├── dto/
│ ├── AuthRequest.java # Login request DTO
│ ├── AuthResponse.java # Login response DTO
│ └── ProductDto.java # Product DTO
├── entity/
│ ├── User.java # User entity
│ └── Product.java # Product entity
├── repository/
│ ├── UserRepository.java # User data access
│ └── ProductRepository.java # Product data access
├── security/
│ ├── JwtTokenUtil.java # JWT utility functions
│ └── JwtRequestFilter.java # JWT filter for requests
└── service/
├── CustomUserDetailsService.java # User authentication service
└── ProductService.java # Product business logic
Getting Started
Prerequisites
- Java 21 or higher
- Maven 3.6+
- curl (for testing scripts)
Installation
- Clone the repository:
git clone <repository-url>
cd api-sessions
- Build the project:
./mvnw clean install
- Run the application:
./mvnw spring-boot:run
The application will start on http://localhost:8080
Initial Data
Users
The application initializes with the following users:
| Username | Password | Role | |
|---|---|---|---|
| admin | admin123 | ROLE_ADMIN | admin@example.com |
| user | user123 | ROLE_USER | user@example.com |
| john | john123 | ROLE_USER | john@example.com |
Products
8 sample products are created in categories: Electronics, Accessories, Audio, and Gaming.
API Endpoints
Authentication
Login
POST /api/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "admin123"
}
Response:
{
"token": "eyJhbGciOiJIUzI1NiJ9...",
"username": "admin",
"message": "Authentication successful"
}
Check Status
GET /api/auth/status
Authorization: Bearer <token>
Response:
{
"username": "admin",
"message": "Authenticated"
}
Products (All require JWT token)
Get All Products
GET /api/products
Authorization: Bearer <token>
Get Product by ID
GET /api/products/{id}
Authorization: Bearer <token>
Search Products by Name
GET /api/products/search?name=laptop
Authorization: Bearer <token>
Get Products by Category
GET /api/products/category/{category}
Authorization: Bearer <token>
Create Product
POST /api/products
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "New Product",
"description": "Product description",
"price": 99.99,
"stock": 10,
"category": "Electronics"
}
Update Product
PUT /api/products/{id}
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "Updated Product",
"description": "Updated description",
"price": 149.99,
"stock": 15,
"category": "Electronics"
}
Delete Product
DELETE /api/products/{id}
Authorization: Bearer <token>
Testing Scripts
Full Test Suite
Run comprehensive tests covering all CRUD operations:
chmod +x test-api.sh
./test-api.sh
This script tests:
- ✓ Authentication (Login)
- ✓ Authorization (JWT Token)
- ✓ CREATE - New product
- ✓ READ - All products, by ID, search, by category
- ✓ UPDATE - Existing product
- ✓ DELETE - Product removal
- ✓ Security - Unauthorized access protection
Quick Test
Run a quick test of basic operations:
chmod +x quick-test.sh
./quick-test.sh
Manual Testing Examples
- Login and save token:
TOKEN=$(curl -s -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}' | \
grep -o '"token":"[^"]*' | cut -d'"' -f4)
echo $TOKEN
- Get all products:
curl -X GET http://localhost:8080/api/products \
-H "Authorization: Bearer $TOKEN"
- Create a product:
curl -X POST http://localhost:8080/api/products \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Smart Watch",
"description": "Fitness tracker with heart rate monitor",
"price": 199.99,
"stock": 25,
"category": "Wearables"
}'
- Update a product:
curl -X PUT http://localhost:8080/api/products/1 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Product Name",
"description": "Updated description",
"price": 299.99,
"stock": 30,
"category": "Electronics"
}'
- Delete a product:
curl -X DELETE http://localhost:8080/api/products/9 \
-H "Authorization: Bearer $TOKEN"
H2 Database Console
Access the H2 console at: http://localhost:8080/h2-console
Connection settings:
- JDBC URL:
jdbc:h2:mem:testdb - Username:
sa - Password: (leave empty)
Configuration
The application can be configured in src/main/resources/application.properties:
# Server Configuration
server.port=8080
# H2 Database
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=
# JWT Configuration
jwt.secret=MySecretKeyForJWTTokenGenerationAndValidationMustBeAtLeast256BitsLong
jwt.expiration=86400000 # 24 hours in milliseconds
Security Features
- Stateless Sessions: JWT-based authentication with stateless session management
- Password Encryption: BCrypt password hashing
- Token Validation: JWT tokens validated on every request
- Authorization: Protected endpoints require valid JWT token
- CSRF Protection: Disabled for REST API
- H2 Console Access: Publicly accessible for development (disable in production)
Error Handling
The API returns appropriate HTTP status codes:
200 OK- Successful operation201 Created- Resource created successfully401 Unauthorized- Invalid or missing JWT token404 Not Found- Resource not found500 Internal Server Error- Server error
Development Notes
JWT Token
- Tokens expire after 24 hours (configurable)
- Tokens are stateless and contain user information
- Each request validates the token signature
Database
- H2 in-memory database is reset on application restart
- Data is re-initialized on each startup
- Use JPA configuration to switch to persistent database
Logging
- Debug logging enabled for security and application packages
- View detailed authentication flow in console logs
Production Considerations
Before deploying to production:
- Change JWT Secret: Use a strong, randomly generated secret key
- Use Persistent Database: Replace H2 with PostgreSQL/MySQL
- Disable H2 Console: Set
spring.h2.console.enabled=false - Configure HTTPS: Enable SSL/TLS for secure communication
- Adjust Token Expiration: Set appropriate token lifetime
- Add Rate Limiting: Prevent brute force attacks
- Implement Refresh Tokens: For better token management
- Add Input Validation: Validate all user inputs
- Configure CORS: Set appropriate CORS policies
- Add Monitoring: Implement logging and monitoring solutions
License
This is a demonstration project for educational purposes.
Author
Developed as a Spring Boot REST API demonstration project with JWT authentication and CRUD operations.
Support
For issues or questions, please check the application logs or review the test scripts for usage examples.