This project demonstrates how to implement Redis-backed session management using Spring Boot and Docker. It provides a ready-to-use template for login, session retrieval, validation, extension, logout, and user-wide session termination.
Sessions are managed as Redis keys with TTL, enabling:
- Stateless APIs with centralized session control
- Fast session lookups
- Expiration-based invalidation
- Multi-session users and bulk termination
- Redis-powered session store (fast reads/writes)
- Login, validate, extend, logout, terminate-all endpoints
- Multi-session per user; list active sessions
- Client IP capture (
X-Forwarded-For/X-Real-IPaware) - Error handling with
UnauthorizedException&NotFoundException - CORS enabled for all origins (demo-friendly)
- Optional Actuator health/metrics
graph TD
A[Client Applications] -->|HTTP Requests| B[Spring Boot REST API]
B -->|Session Ops| C[SessionService]
C -->|Store/Retrieve| D[Redis]
- Java 21 or higher
- Maven 3.6 or higher
- Docker & Docker Compose
- (Optional) Postman for API testing
git clone https://github.com/MenekseYuncu/redis-dockerizer.git
cd redis-dockerizer/key-managementdocker-compose up -dRedis will be available on localhost:6379.
./mvnw clean install./mvnw spring-boot:runThe service starts at http://localhost:<your-port> (configure in application.yml).
src/main/resources/application.yml (example):
spring:
data:
redis:
host: localhost
port: 6379
timeout: 60s
server:
port: 8083 # change as you prefer
logging:
level:
com.redisdockerizer.keymanagement: DEBUG
org.springframework.data.redis: DEBUGNote: Session TTL and key patterns are handled inside
SessionService. Adjust there as needed for your policies (e.g., default TTL, sliding extension).
All endpoints are under the base path /api/sessions.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/sessions/login |
Authenticate and create a session. |
GET |
/api/sessions/{sessionId} |
Get session details by ID. |
DELETE |
/api/sessions/{sessionId}/logout |
Logout (delete) a session by ID. |
GET |
/api/sessions/active |
Get all active session IDs. |
GET |
/api/sessions/user/{userId} |
Get all active session IDs for a user. |
PUT |
/api/sessions/{sessionId}/extend |
Extend a session by minutes (default 30). |
DELETE |
/api/sessions/user/{userId}/terminate-all |
Terminate all sessions for a user. |
POST |
/api/sessions/validate?sessionId=... |
Validate a session and return user info. |
# Unit tests
./mvnw test
# Integration tests
./mvnw verify- Import the Postman collection from: Postman Collection
- Set the base URL to
http://localhost:8083 - Explore all available endpoints
Replace
8083with your configured port.
Request
curl -X POST http://localhost:8083/api/sessions/login \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"secret"}'Sample Response
{
"sessionId": "sess_f521099429074d818cb8fa1010e17218",
"userId": 10,
"username": "alice",
"roles": ["USER"],
"expiresAt": "2025-08-31T22:33:52.538465",
"message": "Login successful"
}curl http://localhost:8083/api/sessions/<SessionId>Sample Response
{
"sessionId": "sess_716d0de39f66402dbecff0a01c99eb2b",
"userId": 10,
"username": "alice",
"roles": ["USER"],
"createdAt": "2025-08-31T22:03:34.816054",
"expiresAt": "2025-08-31T22:33:34.816054",
"clientIp": "0:0:0:0:0:0:0:1"
}404 if not found or expired.
curl -X POST "http://localhost:8083/api/sessions/validate?sessionId=a1b2c3d4e5f6..."Sample Response
{
"valid": true,
"userId": 10,
"username": "alice",
"roles": ["USER"],
"error": null
}curl -X PUT "http://localhost:8083/api/sessions/<SessionId>/extend?minutes=45"Sample Response
{
"message": "Session extended successfully",
"sessionId": "sess_043196ed83b3444da3c17d63eedd039e",
"extendedByMinutes": 45
}curl -X DELETE http://localhost:8083/api/sessions/<SessionId>/logoutSample Response
{
"message": "Logout successful",
"data": { "sessionId": "sess_711as3..." }
}curl http://localhost:8083/api/sessions/activeSample Response
{
"activeSessions": [
"sess_716d0de39f66402dbecff0a01c99eb2b"
],
"count": 1
}curl http://localhost:8083/api/sessions/user/<UserId>Sample Response
{
"userId": 10,
"sessions": ["sess_71...","sess_74..."],
"count": 1
}curl -X DELETE http://localhost:8083/api/sessions/user/<UserId>/terminate-allSample Response
{
"message": "User sessions terminated",
"userId": 10,
"terminatedCount": 2
}- Centralized session validation for stateless microservices
- Multi-session users (e.g., web + mobile) with per-user oversight
- Bulk logout / kill-switch for compromised accounts
- Short-lived access with TTL & sliding extension
- Audit & monitoring via active session listing
-
CORS:
@CrossOrigin(origins = "*")is enabled for demo convenience—restrict in production. -
IP Extraction: The controller uses
X-Forwarded-For→X-Real-IP→remoteAddr. Ensure your proxy sets these headers. -
TTL / Sliding Extension: Implemented in
SessionService. Choose a default TTL and extend logic that fits your security posture. -
Error Semantics:
UnauthorizedExceptionfor invalid/expired sessions (e.g., during validation)NotFoundExceptionfor missing sessions (e.g., logout/get by ID/extend)
Actual key names may differ in your implementation; adjust as needed.
session:{sessionId}→ session hash / JSON with TTLuser:{userId}:sessions→ set of session IDssessions:active→ set of active session IDs
- Enable Redis AUTH/ACL and TLS in production
- Do not expose Redis directly to the public internet
- Rotate secrets regularly; monitor access logs
- Consider IP/device binding and max session limits per user
- Use short TTLs and explicit refresh flows for sensitive apps
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push the branch (
git push origin feature/amazing-feature) - Open a Pull Request