Menu

Backend & APIs Topic

OAuth2 & JWT Auth systems

This tutorial covers the fundamental concepts, while the other topics listed on the left provide more detailed explanations.

Core Concepts & Relationship

  • OAuth 2.0: Primarily an authorization framework. It's about granting access to resources without sharing credentials. The classic question it answers is: "How can I allow a third-party application to access my data on another service (like Google or Facebook) without giving it my password?"

  • JWT (JSON Web Token): A compact, self-contained way to securely transmit information between parties as a JSON object. It's a token format. This information can be verified and trusted because it is digitally signed.

The Key Relationship: OAuth 2.0 defines the process of getting a token. JWT often defines the structure of that token. So, you use the OAuth 2.0 flow to get an access token, and that access token is frequently a JWT.


1. OAuth 2.0 (The Authorization Framework)

OAuth 2.0 is about delegating access. It involves four main roles:

  1. Resource Owner: The user who owns the data (e.g., you).

  2. Client: The application that wants to access the user's data (e.g., "Spotify.com").

  3. Authorization Server: The server that authenticates the user and issues tokens (e.g., "login.with.google.com"). This is where the magic happens.

  4. Resource Server: The API that holds the user's data (e.g., "googleapis.com/drive"). It accepts the access token to fulfill requests.

Common OAuth 2.0 Flows (Grants)

Different flows are used for different types of clients:

  • Authorization Code Flow (Most Common & Secure):

    • Used by web applications that have a server-side component.

    • Steps:

      1. The app redirects the user to the Authorization Server.

      2. The user authenticates and consents to the permissions.

      3. The Authorization Server redirects the user back to the app with a short-lived Authorization Code.

      4. The app's backend exchanges this code for an Access Token (and often a Refresh Token).

    • Why secure? The access token is never exposed to the user's browser.

  • Authorization Code Flow with PKCE (Proof Key for Code Exchange):

    • An enhanced version of the Authorization Code Flow for mobile apps and Single-Page Applications (SPAs) that cannot securely store a client secret.

    • The client creates a secret (a "code verifier") and proves it owns it during the token exchange, preventing interception attacks.

  • Client Credentials Flow:

    • Used for machine-to-machine (M2M) communication where a specific user context isn't needed (e.g., a backend service accessing another API).

    • The client application authenticates with its own credentials (Client ID & Secret) to get an access token.

  • Resource Owner Password Credentials Flow:

    • The user provides their username and password directly to the client application, which uses them to get a token.

    • Not recommended unless you absolutely trust the application (e.g., it's your own first-party mobile app).


2. JWT (JSON Web Token) (The Token Format)

A JWT is a string composed of three parts, separated by dots (.): Header.Payload.Signature

  • Header: Contains the token type (JWT) and the signing algorithm (e.g., HS256 or RS256).

    json

    {
      "alg": "HS256",
      "typ": "JWT"
    }
  • Payload: Contains the claims—statements about an entity (typically the user) and additional metadata.

    json

    {
      "sub": "1234567890",        // Subject (user ID)
      "name": "John Doe",
      "iat": 1516239022,          // Issued At (timestamp)
      "exp": 1516242622           // Expiration Time (timestamp)
    }
  • Signature: To create the signature, you take the encoded header, the encoded payload, a secret (or private key), and the algorithm specified in the header, and sign them. This ensures the token hasn't been tampered with.

Key JWT Characteristics:

  • Self-Contained: The payload contains all the necessary user data, so the Resource Server doesn't need to query a database to validate the user for every request (stateless).

  • Verifiable: The signature can be verified by anyone who knows the secret (or has the public key, in the case of asymmetric algorithms like RS256).

  • Not Encrypted: The payload is only Base64Url encoded, which is easily reversible. Never store sensitive data (like passwords) in a JWT.


How They Work Together: A Typical System

Let's build a modern system using all the technologies we've discussed.

Scenario: A user logs into "MyCoolApp.com" using "Login with Google," and then their browser fetches real-time data.

  1. OAuth 2.0 Flow (Authorization Code with PKCE):

    • The user clicks "Login with Google" on MyCoolApp (the Client).

    • MyCoolApp redirects the user to Google's Authorization Server.

    • The user logs in and consents.

    • Google redirects back to MyCoolApp with an authorization_code.

    • MyCoolApp's backend exchanges the code for an Access Token. This Access Token is a JWT.

  2. JWT in Action:

    • The MyCoolApp backend (or frontend) stores this JWT.

    • For every subsequent API request to the MyCoolApp Resource Server (e.g., to api.mycoolapp.com/data), the client includes the JWT in the Authorization header: Bearer <JWT_TOKEN>.

    • The MyCoolApp Resource Server:

      • Verifies the JWT signature using a public key (if using RS256) to ensure it was issued by its trusted Authorization Server and hasn't been tampered with.

      • Checks the standard claims like exp (expiration) and iat (issued at).

      • Extracts user data (like user_id and scopes) from the JWT payload without needing to make a database call. This is the stateless benefit.

  3. Integration with gRPC & Event-Driven Systems:

    • gRPC: The JWT can be sent as a metadata header (similar to an HTTP header) in a gRPC call. The gRPC service can then verify the JWT to authenticate the internal service or user making the request.

    • Event-Driven: When an event like UserLoggedIn is published, the JWT's payload (the user ID) can be included in the event, so all consuming services know which user the event pertains to.

  4. Integration with WebSockets:

    • When the WebSocket connection is first established, the client can send the JWT over the connection (e.g., as the first message or in a query parameter during the initial HTTP handshake).

    • The server verifies the JWT to authenticate the user and associate the WebSocket connection with that specific user ID. All subsequent messages over that socket are now linked to an authenticated user.

Security Considerations

  • JWT Security:

    • Short Expiry: Access Tokens (JWTs) should have short lifespans (minutes/hours).

    • Use Refresh Tokens: To get a new Access Token without asking the user to log in again, use a long-lived, securely stored Refresh Token.

    • Secure Storage: Store JWTs securely. For browsers, use HttpOnly cookies to prevent access via JavaScript (mitigating XSS). For mobile apps, use secure storage.

  • OAuth 2.0 Security:

    • Always use HTTPS.

    • For SPAs and mobile apps, use PKCE.

    • Validate all redirect URIs on the Authorization Server.

In summary, OAuth 2.0 is the "what" (the protocol for getting permission), and JWT is the "how" (a specific, efficient format for representing that permission). Together, they form the backbone of secure, scalable authentication and authorization for modern applications.

Comments (0)

No comments yet. Be the first to comment!

LecturreAI Assistant

Hello! I'm LecturreAI

What would you like to learn today?