JWT Authentication Strategy
Relevant source files
The following files were used as context for generating this wiki page:
- src/main/java/org/example/coding_convention/config/filter/JwtAuthFilter.java
- src/main/java/org/example/coding_convention/config/filter/LoginFilter.java
- src/main/java/org/example/coding_convention/user/controller/AuthController.java
- src/main/java/org/example/coding_convention/user/service/AuthService.java
- src/main/java/org/example/coding_convention/utils/JwtUtil.java
- src/main/java/org/example/coding_convention/config/SecurityConfig.java
- src/main/java/org/example/coding_convention/config/oauth/OAuth2AuthenticationSuccessHandler.java
- src/main/java/org/example/coding_convention/config/interceptor/JwtHandshakeInterceptor.java
The PhanesEditor project employs a JSON Web Token (JWT) based authentication strategy to secure its collaborative code editing environment. This strategy facilitates stateless authentication across RESTful APIs and real-time WebSocket connections. By utilizing JWTs, the system eliminates the need for server-side session storage, allowing for scalable user verification and access control for project-based collaboration.
The implementation covers local login via JSON credentials, OAuth2 social login (Kakao/Google), and token-based authorization for every subsequent request. Tokens are primarily stored in HTTP-only cookies to mitigate XSS risks, while also supporting standard Authorization headers for flexibility.
Sources: README.md, src/main/java/org/example/coding_convention/config/SecurityConfig.java
Authentication Flow
The authentication process is divided into two main phases: Token Issuance (Login) and Token Verification (Authorization).
Token Issuance (Login)
Users can authenticate via a local login endpoint or through OAuth2 providers. Upon successful authentication, the server generates a JWT containing user identity information (email, idx, nickname) and returns it to the client.
The system uses LoginFilter to handle JSON-based login requests and OAuth2AuthenticationSuccessHandler for social logins. Both utilize JwtUtil to create the final token.
Sources: src/main/java/org/example/coding_convention/config/filter/LoginFilter.java:31-72, src/main/java/org/example/coding_convention/config/oauth/OAuth2AuthenticationSuccessHandler.java:27-42
Token Verification (Authorization)
For every request to a protected resource, the JwtAuthFilter intercepts the request, extracts the token, and populates the SecurityContext.
The filter checks for the token in the SJB_AT cookie first, falling back to the Authorization: Bearer <token> header if the cookie is absent.
Sources: src/main/java/org/example/coding_convention/config/filter/JwtAuthFilter.java:23-76
Core Components
Security Configuration
SecurityConfig acts as the central hub for security settings, defining which paths are public and which require authentication.
| Feature | Implementation Detail |
|---|---|
| Password Encoding | BCryptPasswordEncoder |
| CORS Policy | Allowed Origins: gomorebi.kro.kr, localhost:5173 |
| CSRF | Disabled for REST API compatibility |
| Filters | JwtAuthFilter placed before UsernamePasswordAuthenticationFilter |
Sources: src/main/java/org/example/coding_convention/config/SecurityConfig.java:45-104
JWT Utility (JwtUtil)
This utility class manages the lifecycle of the JWT, including generation, parsing, and deletion.
- Secret Key: Managed via HMAC-SHA keys (
HS256). - Expiration: Set to 240 minutes (
1000 * 60 * 240L). - Claims: Includes
idx,email,nickname, and a defaultroleof "USER".
Sources: src/main/java/org/example/coding_convention/utils/JwtUtil.java:16-35
WebSocket Security
Since WebSockets do not use standard HTTP filters after the initial handshake, PhanesEditor uses a JwtHandshakeInterceptor to authenticate users during the connection phase.
- Handshake Interception: Before the WebSocket connection is established, the interceptor extracts the JWT from the request cookies.
- Authentication Storage: If valid, the user's
Authenticationobject is placed into the WebSocket session attributes (attributes.put("auth", authentication)). - Real-time Access Control: This ensures only authenticated users can participate in room-based chat or collaborative editing.
Sources: src/main/java/org/example/coding_convention/config/interceptor/JwtHandshakeInterceptor.java:32-72
API Reference: Authentication Endpoints
The following table summarizes the primary authentication-related endpoints defined in the controllers.
| Endpoint | Method | Description | Sources |
|---|---|---|---|
/api/login | POST | Main JWT login (handled by LoginFilter) | SecurityConfig.java:78 |
/auth/login | POST | Alternative login via AuthService | AuthController.java:25 |
/user/signup | POST | Register new user and trigger email verification | UserController.java:55 |
/user/verify | GET | Complete email verification via UUID | UserController.java:101 |
/user/logout | POST | Expires the SJB_AT cookie | UserController.java:112 |
Token Payload Structure
The system expects a JWT with the following standard claims:
{
"idx": "1",
"email": "user@example.com",
"nickname": "DevUser",
"role": "USER",
"exp": 1724000000
}
Sources: src/main/java/org/example/coding_convention/utils/JwtUtil.java:23-28
Conclusion
The JWT Authentication Strategy in PhanesEditor provides a robust foundation for both stateless HTTP interactions and stateful WebSocket communications. By integrating JWT verification into the handshake process and maintaining a standard security filter chain, the project ensures that collaborative features like real-time code editing and project-specific chat remain restricted to authorized members.