The SkillForge User Service is a Spring Boot microservice responsible for user management, authentication, and user-related operations in the SkillForge learning platform. It provides comprehensive user functionality including registration, authentication, profile management, course interactions, and skill tracking.
The user service is built with:
- Spring Boot 3.x: Core application framework
- Spring Security: Authentication and authorization
- Spring Data MongoDB: Data persistence
- JWT (JSON Web Tokens): Stateless authentication
- OpenAPI 3.0: API documentation with Swagger UI
- BCrypt: Password hashing and security
- User registration and authentication
- Profile management (CRUD operations)
- Password security with BCrypt hashing
- User search and discovery
- Course enrollment and unenrollment
- Course bookmarking and unbookmarking
- Course completion tracking
- Skills acquisition tracking
- JWT token generation and validation
- Stateless authentication
- Role-based access control
- Inter-service communication security
- Registration: User provides credentials → BCrypt password hashing → User stored in MongoDB
- Login: User provides credentials → Validation against stored hash → JWT token generation
- Token Validation: JWT token verified on each protected request
- Stateless Sessions: No server-side session storage, all state in JWT tokens
- Request Reception: HTTP request received by controller
- Security Filter: JWT token validation (if required)
- Business Logic: Service layer processes request
- Data Persistence: MongoDB operations via repository layer
- Response: Structured JSON response with appropriate HTTP status
The user service supports secure inter-service communication:
- Service Key Authentication: Internal endpoints protected with
X-Service-Keyheader - Course Service Integration: Allows course service to manage user enrollments, bookmarks, and completions
- Stateless Design: No shared state between services
The service uses JWT tokens for stateless authentication:
// Token Generation
public String generateToken(String userId, String username) {
return Jwts.builder()
.subject(userId)
.claim("username", username)
.issuedAt(now)
.expiration(expiryDate)
.signWith(getSigningKey(), Jwts.SIG.HS256)
.compact();
}POST /api/v1/users/register- User registrationPOST /api/v1/users/login- User authenticationGET /api/v1/users/health- Health checkGET /docs/**- API documentationGET /actuator/*- Monitoring endpoints
- All other
/api/v1/users/**endpoints - User profile operations
- Course interactions
- User search operations
POST /api/v1/users/{userId}/enroll/{courseId}- Course enrollmentDELETE /api/v1/users/{userId}/enroll/{courseId}- Course unenrollmentPOST /api/v1/users/{userId}/bookmark/{courseId}- Course bookmarkingDELETE /api/v1/users/{userId}/bookmark/{courseId}- Course unbookmarkingPOST /api/v1/users/{userId}/complete/{courseId}- Course completion
- BCrypt Hashing: Passwords are hashed using BCrypt with configurable strength
- Salt Generation: Automatic salt generation for each password
- Secure Comparison: Timing-attack resistant password comparison
Environment-specific CORS policies for cross-origin requests:
// Development
config.addAllowedOriginPattern("*");
config.
setAllowedMethods(Arrays.asList("GET", "POST","PUT","DELETE","OPTIONS"));
config.
setAllowedHeaders(List.of("*"));POST /api/v1/users/register- Register a new userPOST /api/v1/users/login- Authenticate user and receive JWT token
GET /api/v1/users/{userId}/profile- Get user profilePUT /api/v1/users/{userId}/profile- Update user profileDELETE /api/v1/users/{userId}/profile- Delete user profile
POST /api/v1/users/{userId}/enroll/{courseId}- Enroll user in courseDELETE /api/v1/users/{userId}/enroll/{courseId}- Unenroll user from coursePOST /api/v1/users/{userId}/bookmark/{courseId}- Bookmark a courseDELETE /api/v1/users/{userId}/bookmark/{courseId}- Unbookmark a coursePOST /api/v1/users/{userId}/complete/{courseId}- Mark course as completed
GET /api/v1/users/{userId}/bookmarks- Get bookmarked coursesGET /api/v1/users/{userId}/courses/enrolled- Get enrolled coursesGET /api/v1/users/{userId}/courses/completed- Get completed coursesGET /api/v1/users/{userId}/courses/bookmarked- Get bookmarked coursesGET /api/v1/users/{userId}/skills- Get user skillsGET /api/v1/users/{userId}/skills-in-progress- Get skills in progress
GET /api/v1/users/with-skill- Find users with specific skillGET /api/v1/users/with-skill-in-progress- Find users learning specific skillGET /api/v1/users/enrolled-in/{courseId}- Find users enrolled in courseGET /api/v1/users/completed/{courseId}- Find users who completed courseGET /api/v1/users/bookmarked/{courseId}- Find users who bookmarked courseGET /api/v1/users/search/user/{username}- Search users by usernameGET /api/v1/users/search/email/{email}- Search users by email
GET /api/v1/users/health- Service health checkGET /actuator/health- Spring Boot health endpointGET /actuator/prometheus- Prometheus metrics
GET /docs- Swagger UI for API documentationGET /user-openapi.yaml- OpenAPI specification
public class User {
private String id;
private String username;
private String email;
private String password; // BCrypt hashed
private String firstName;
private String lastName;
private List<String> enrolledCourses;
private List<String> completedCourses;
private List<String> bookmarkedCourses;
private List<String> skills;
private List<String> skillsInProgress;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}- UserRegisterRequest: Registration data validation
- UserLoginRequest: Authentication credentials
- UserProfileUpdateRequest: Profile update data
- UserLoginResponse: Authentication response with JWT
- UserProfileResponse: User profile data
- UserRegisterResponse: Registration confirmation
# Service Configuration
SERVER_PORT_USER=8082
# MongoDB Configuration
MONGODB_DATABASE=skillforge
MONGO_URL=mongodb://localhost:27017/skillforge
# JWT Configuration
JWT_SECRET=your-secret-key-here
JWT_EXPIRATION_MS=86400000
# Service Keys (for inter-service communication)
COURSE_SERVICE_KEY=course-service-keyserver:
port: ${SERVER_PORT_USER:8082}
address: "0.0.0.0"
spring:
data:
mongodb:
database: ${MONGODB_DATABASE:skillforge}
uri: ${MONGO_URL:mongodb://localhost:27017/skillforge}
jwt:
secret: ${JWT_SECRET:default-secret-key}
expirationMs: ${JWT_EXPIRATION_MS:86400000}- dev: Development configuration with debug logging
- docker: Docker environment configuration
- prod: Production configuration with optimized settings
- test: Test configuration with in-memory database
# 1. Start MongoDB
# On macOS with Homebrew:
brew services start mongodb-community
# On Ubuntu/Debian:
sudo systemctl start mongod
# On Windows:
# Download MongoDB from https://www.mongodb.com/try/download/community and run:
mongod
# Or using Docker:
docker run -d -p 27017:27017 --name mongodb mongo:latest
# 2. Set environment variables (optional - defaults are provided)
export SERVER_PORT_USER=8082
export MONGODB_DATABASE=skillforge
export MONGO_URL=mongodb://localhost:27017/skillforge
export JWT_SECRET=your-secret-key-here
export JWT_EXPIRATION_MS=86400000
# 3. Start the user service
./gradlew bootRun
# Or with specific profile
./gradlew bootRun --args='--spring.profiles.active=dev'# Run all tests
./gradlew test
# Run specific test
./gradlew test --tests UserServiceTest
# Run with coverage
./gradlew test jacocoTestReportOnce the service is running, access the API documentation:
- Swagger UI: http://localhost:8082/docs
- OpenAPI Spec: http://localhost:8082/user-openapi.yaml (This will download the OpenAPI spec file)
- Swagger UI: http://localhost:8081/api/v1/users/docs
- OpenAPI Spec: http://localhost:8081/api/v1/users/user-openapi.yaml (This will download the OpenAPI spec file)
# Connect to MongoDB
mongosh mongodb://localhost:27017/skillforge
# View collections
show collections
# Query users
db.users.find()
# Query specific user
db.users.findOne({username: "testuser"})logging:
level:
com.gitittogether.skillforge.server.user: DEBUG
org.springframework.security: DEBUG
org.springframework.data.mongodb: DEBUG- Service Health:
GET /api/v1/users/health - Spring Boot Health:
GET /actuator/health - Database Connectivity: Included in health checks
- Prometheus Metrics:
GET /actuator/prometheus - Application Metrics: Request counts, response times, error rates
- Database Metrics: Connection pool, query performance
-
Password Security
- BCrypt hashing with configurable strength
- Automatic salt generation
- Secure password comparison
-
JWT Security
- HMAC-SHA256 signing
- Configurable expiration times
- Token validation on every request
-
Input Validation
- Request DTO validation with Bean Validation
- SQL injection prevention (MongoDB)
- XSS protection through proper encoding
-
CORS Configuration
- Environment-specific CORS policies
- Proper preflight request handling
- Secure header configuration
-
Error Handling
- Structured error responses
- No sensitive information leakage
- Proper HTTP status codes
The service includes security headers:
X-Content-Type-Options: nosniffX-Frame-Options: DENYX-XSS-Protection: 1; mode=block
-
MongoDB Connection Errors
- Ensure MongoDB is running and accessible
- Check MongoDB host/port configuration
- Verify database name and authentication
-
JWT Validation Failures
- Check JWT secret configuration
- Verify token format and expiration
- Ensure proper Authorization header format
-
Authentication Issues
- Verify user credentials in database
- Check password hashing configuration
- Ensure JWT secret is consistent across services
-
CORS Errors
- Verify CORS configuration for environment
- Check allowed origins and methods
- Ensure proper preflight request handling
Enable debug logging for troubleshooting:
logging:
level:
com.gitittogether.skillforge.server.user: DEBUG
org.springframework.security: DEBUG
org.springframework.data.mongodb: DEBUG# Check MongoDB status
sudo systemctl status mongod
# Check MongoDB logs
sudo journalctl -u mongod
# Test MongoDB connection
mongosh mongodb://localhost:27017/skillforge --eval "db.runCommand('ping')"- Receives requests through API Gateway
- JWT tokens validated by gateway
- User ID injected via
X-User-Idheader
- Inter-service communication via service keys
- Course enrollment, bookmarking, and completion tracking
- User skill acquisition updates
- Prometheus metrics for monitoring
- Health checks for load balancers
- Structured logging for log aggregation