🔑 JWT Tokens VS Session Cookies in Authentication and Authorization 🍪

Truong Phung - Oct 22 - - Dev Community

First thing first, let's briefly talk about the mechanism of each approach.

1. The way session cookies work

Session cookies are small pieces of data stored on the client side (typically in the browser) that are used to maintain user session state between requests. Here’s a brief explanation of how they work:

  1. Creation: When a user logs into a web application, the server generates a session identifier (session ID) and sends it to the client as a session cookie. This cookie usually has attributes like HttpOnly (to prevent access via JavaScript), Secure (to ensure it’s sent only over HTTPS), and an expiration time.

  2. Storage: The browser stores the session cookie, associating it with the domain of the web application.

  3. Transmission: On subsequent requests to the same domain, the browser automatically includes the session cookie in the HTTP headers. This allows the server to identify the user and retrieve their session data (like user preferences or authentication status).

  4. Session Management: The server maintains a mapping between the session ID stored in the cookie and the user’s session data (often stored in memory or a database). When the server receives a request with a session cookie, it looks up the session ID to access the associated data.

  5. Expiration: Session cookies are typically temporary and expire when the user closes the browser or after a certain period of inactivity. Once expired, the session ID becomes invalid, and the user will need to log in again to create a new session.

Session cookies facilitate maintaining user state across multiple HTTP requests by storing a session ID that the server uses to track user sessions, providing a seamless experience while ensuring security through attributes like HttpOnly and Secure.

2. JWT token mechanism

JWT (JSON Web Token) is a compact and self-contained way of securely transmitting information between parties as a JSON object. It is widely used for authentication and authorization mechanisms. Here’s a brief overview of how the JWT token mechanism works:

1. Structure of JWT:

A JWT consists of three parts, separated by dots (.):

  • Header: Contains metadata about the token, such as the type of token (JWT) and the signing algorithm (e.g., HS256).
  • Payload: Contains the claims. Claims are statements about an entity (typically the user) and additional data. It could include user information like userId, username, and roles.
  • Signature: Used to verify the token’s authenticity and ensure that the token hasn’t been altered. It is created by encoding the header and payload and signing it with a secret key.

Example JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsInJvbGUiOiJhZG1pbiJ9.sj5QDLsZBfEtpM1Y18kLgLw_2z3j4XnZW3x2uD8-QWI
Enter fullscreen mode Exit fullscreen mode

2. How JWT Works:

The JWT mechanism involves three main steps: generation, transmission, and verification.

  1. Generation:

    The server generates a JWT when a user logs in or authenticates. It encodes the user's data (like userId) in the payload, then signs the token using a secret key.

    Example in Golang:

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
        "userId": 1,
        "role": "admin",
    })
    tokenString, err := token.SignedString([]byte("your-secret-key"))
    
  2. Transmission:

    The server sends the JWT back to the client (often in the response body or as an HTTP-only cookie).
    The client stores the token (typically in localStorage, sessionStorage, or a cookie) and includes it in the Authorization header of subsequent requests.

    Example:

    Authorization: Bearer <token>
    
  3. Verification:

  • When the client sends a request with the token, the server verifies the token's signature using the secret key.
  • If the token is valid, the server extracts the user data from the payload and proceeds with the request.
  • Example in Golang:

    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        return []byte("your-secret-key"), nil
    })
    

3. Why Use JWT:

  • Stateless: JWTs are stateless, meaning the server doesn’t need to store session data. All necessary user information is embedded in the token.
  • Scalable: Because of their stateless nature, JWTs are suitable for distributed systems, like microservices, where session state is difficult to manage.
  • Secure: When properly used, JWTs provide a secure way to handle user authentication. The signature ensures that data hasn't been tampered with.

4. JWT Claims:

  • Registered claims: Predefined claims like iss (issuer), exp (expiration time), sub (subject), aud (audience).
  • Public claims: Custom claims created by the user. Example: userId, role.
  • Private claims: Claims that are agreed upon between the server and client, and not part of any standard.

5. Common Use Cases:

  • Authentication: After successful login, a JWT is returned and used to authenticate the user for future requests.
  • Authorization: The token’s payload can include user roles, and the server can check these roles to allow or restrict access to resources.

6. Security Considerations:

  • Secret Key: Always keep the signing secret key secure. If compromised, attackers could generate valid tokens.
  • Expiration: Use short-lived tokens (exp) to limit the window of opportunity for token misuse.
  • HTTPS: Always use JWT over HTTPS to prevent man-in-the-middle (MITM) attacks.

7. About Secret Key

  • A secret key is crucial when creating and parsing JWT tokens because it ensures the integrity and authenticity of the token. Here’s why it is needed:
  • Creating a Token: When generating a JWT, the secret key is used to sign the token. This process produces a signature that combines the header, payload, and secret key. The signature helps ensure that the token has not been tampered with.
  • Parsing/Verifying a Token: When the server receives a JWT, it uses the same secret key to verify the token's signature. If the signature matches, it confirms that the token's data is authentic and hasn’t been altered since it was issued.
  • Without a shared secret key, anyone could create or modify tokens, making the authentication mechanism insecure.

JWTs are a powerful mechanism for securing APIs and managing authentication in a scalable way, especially in stateless and microservice architectures. However, they require careful handling of security practices to ensure they are used safely.

3. Authentication and Authorization

Session Cookie:

  • Authentication: Stores session data on the server and uses a cookie to hold a session ID that links to this data. The server validates the session ID to authenticate the user.
  • Authorization: User data and roles are typically stored in the session on the server, making it easy to check permissions.
  • Stateful: Requires server-side storage and management of user sessions.

JWT Token:

  • Authentication: Uses a token that is generated and signed (often using a secret key). The token is self-contained and sent with each request, allowing the server to verify the user’s identity.
  • Authorization: Contains claims (user data, roles) embedded within the token, making it easy to verify permissions without server-side storage.
  • Stateless: Does not require server-side storage, as all information is contained within the token itself.

4. Why Prefer JWT Token Over Session Cookies?

  • Scalability: JWT is stateless, so it doesn’t require server-side session storage, making it easier to scale across multiple servers without needing to share session state.
  • Decentralized Authentication: JWTs can be verified by any server with the secret key, allowing for easier distributed authentication in microservices architectures.
  • Self-contained: JWTs carry user claims (like roles or permissions) within the token, reducing the need for frequent database lookups.
  • Cross-domain Support: JWTs can be easily used in cross-domain scenarios (e.g., APIs), while cookies often face restrictions like SameSite policies.

However, JWTs can be more complex to manage securely, as they require careful handling of expiration and revocation.

If you found this helpful, let me know by leaving a 👍 or a comment!, or if you think this post could help someone, feel free to share it! Thank you very much! 😃

. . . . . . . . . . . . . . . . . . . . . . . . . . .