DEV Community

Diego Liascovich
Diego Liascovich

Posted on

πŸ” Secure Web Application Flow with JWT: From Frontend to Backend

By Diego Liascovich

Full-Stack Developer | Microservices | Angular | Node.js

Modern web applications rely heavily on JSON Web Tokens (JWT) for stateless authentication and secure communication between the frontend and backend.

In this article, we’ll explore the step-by-step security flow using JWT, from the moment a user logs in to the backend verifying their access, including refresh token strategies and best practices.


πŸ”‘ 1. User Login Request

The user enters their credentials on the frontend (e.g., Angular, React).

The frontend sends a POST /login request to the backend:

POST /login
{
  "email": "user@example.com",
  "password": "123456"
}
Enter fullscreen mode Exit fullscreen mode

🧠 2. Backend Authenticates and Issues JWT

  • Backend validates credentials.
  • If valid, it generates a signed JWT (e.g. using HMAC SHA-256).
  • Optional: also returns a refresh token.
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "..." (optional)
}
Enter fullscreen mode Exit fullscreen mode

JWT contains non-sensitive info like userId, role, exp.


πŸ“¦ 3. Frontend Stores the Token

Options:

  • localStorage or sessionStorage (easier, but vulnerable to XSS)
  • HttpOnly Secure Cookie (safer against XSS)

βœ… Recommended: Use cookies with HttpOnly, Secure, and SameSite=Strict when possible.


πŸ” 4. Accessing Protected Resources

The frontend includes the accessToken in the Authorization header:

GET /orders
Authorization: Bearer <access_token>
Enter fullscreen mode Exit fullscreen mode

πŸ”Ž 5. Backend Verifies JWT

Steps the backend performs:

  1. Extracts token from Authorization header.
  2. Verifies the signature using the secret.
  3. Checks exp and optional claims like role.

If valid β†’ user is authorized.

If invalid/expired β†’ responds with 401 Unauthorized.


πŸ” 6. Refreshing the Token (Optional)

If the accessToken is expired, the frontend can request a new one using the refreshToken:

POST /refresh-token
Authorization: Bearer <refresh_token>
Enter fullscreen mode Exit fullscreen mode

The backend verifies the refresh token and responds with a new accessToken.


πŸšͺ 7. Logout Flow

Frontend clears the token from storage.

If using cookies: optionally hit a /logout endpoint to invalidate the refresh token on the server.


πŸ“¦ Example JWT Payload

{
  "sub": "user_123",
  "email": "user@example.com",
  "role": "admin",
  "iat": 1721234567,
  "exp": 1721242167
}
Enter fullscreen mode Exit fullscreen mode

βœ… Best Practices

  • βœ… Use HTTPS always.
  • βœ… Use short accessToken lifespan (5–15 mins).
  • βœ… Sign tokens securely (HS256, RS256).
  • βœ… Store tokens safely (prefer HttpOnly cookies).
  • βœ… Validate tokens on every request.

🧭 Summary

JWT enables secure, stateless authentication β€” but only if implemented correctly.

From login to logout, your frontend and backend should follow a strict protocol for storing, sending, and validating tokens. When done right, JWTs make modern apps both user-friendly and secure. πŸ”

Let me know if you'd like to see full implementation examples in Angular and Node.js!

Top comments (0)