Authentication and Authorization - the correct way!

Prathmesh Jagtap - Oct 8 - - Dev Community

Imagine you’re building a web or mobile app that needs to verify users — maybe for a social media platform, an e-commerce site, or even just a simple dashboard. At some point, you’ll ask yourself, “How do I keep my users logged in securely?”

That’s where authentication comes into play. But with so many different methods to choose from — like session management, auth tokens, and the increasingly popular JWT (JSON Web Token) — it can be not very clear to figure out which one is right for your app. So how do you decide?

If you’ve been hearing a lot about JWT and wondering whether it’s worth the hype, you’re in the right place. In this blog post, we’re going to break down what JWT is, how it works, and how it stacks up against other common authentication methods in Django. By the end, you’ll have a clear understanding of when to use JWT and how it compares to other options like session-based authentication and auth tokens. Let’s dive in!

What is JWT (JSON Web Token)?

JWT (JSON Web Token) is a compact, URL-safe token format used to securely transmit information between parties. It is commonly used in authentication processes where a client requests access to resources, such as in web or mobile applications.

A JWT is made up of three parts:

Header: Contains metadata about the token, such as the type (JWT) and the signing algorithm (e.g., HS256).

Payload: Contains user-specific claims, like the user’s ID, username, or role.

Signature: Ensures that the token hasn’t been tampered with by signing the header and payload with a secret key.

A sample JWT might look like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImpvaG4iLCJleHAiOjE2MjEyMzY5MjZ9.GG7h8oV2C7Mcp93JK...
Enter fullscreen mode Exit fullscreen mode

JWT is commonly used in stateless authentication, meaning the server doesn’t store session data. Instead, all the necessary information (claims) is embedded in the token itself.

How JWT Works: A Step-by-Step Process

Let’s break down how JWT authentication works with a simple scenario:

1. User Logs In
A user submits their email and password via a login form. The server validates the credentials, and if they are correct, the server generates a JWT that contains the user’s information (like their id, username, and role).

2. Token Sent to the Client
Once the JWT is generated, it is sent back to the client, usually in the response body. The client stores this token (in localStorage or sessionStorage for a browser, or securely on a mobile device).

3. User Requests Protected Resources
Whenever the client needs to access a protected route, it sends the JWT in the Authorization header of the request:

Authorization: Bearer <JWT_TOKEN>

Enter fullscreen mode Exit fullscreen mode

The server then verifies the token, ensuring its validity and integrity, before granting access to the resource.

4. Token Expiration and Refresh
Since JWT tokens have an expiration time (e.g., 5 minutes), once they expire, the user can send a refresh token to get a new JWT without needing to log in again.

5. User Logs Out
When the user logs out, the refresh token is typically blacklisted (in setups that support blacklisting), ensuring the user is effectively logged out and cannot refresh the token anymore.

JWT vs. Traditional Authentication Methods in Django

JWT is one of many ways to implement authentication in Django applications. Let’s take a look at how JWT compares to other common methods such as session management and auth tokens.

1. JWT Authentication vs. Session Management

Session Management:
In session-based authentication, once a user logs in, the server creates a session and stores it in the database or memory. A session ID is then sent to the client via cookies. The client stores the session ID and sends it with every request. The server then retrieves the session data from the storage to identify the user.

Real-World Scenario:

E-commerce Website: Imagine you log in to an online store, add items to your cart, and proceed to checkout. Every action during this session, like viewing products or updating the cart, is tied to your session ID stored on the server. Once you log out, the session is destroyed.

JWT vs. Sessions:

- Storage:

  • JWT: Stateless, no server-side storage. All data is contained within the token itself.
  • Sessions: Stateful, the server stores session data (usually in a database or memory), and a session ID is sent to the client.

- Scalability:

  • JWT: Highly scalable; no need to store user session information, making it easy to scale horizontally across servers.
  • Sessions: Less scalable; requires managing and sharing session data across servers (e.g., using a centralized session store).

- Data Transfer:

  • JWT: The token includes all user data (claims) and is sent with each request. It can become large if too much data is included.
  • Sessions: Only a session ID is sent, and user data is retrieved from the server.

- Security:

  • JWT: Vulnerable if tokens are not stored securely on the client (e.g., local storage). It’s important to handle token expiration and refresh securely.
  • Sessions: Typically uses cookies for storing the session ID, which are more secure if HTTP-only and Secure flags are used. However, it can be vulnerable to CSRF attacks.

- Expiration & Management:

  • JWT: Tokens have an expiration time. If a refresh token is used, the access token can be renewed without re-authentication.
  • Sessions: Sessions also have a timeout period, but can easily be extended as long as the user is interacting with the app.

- Token Size:

  • JWT: Since all data is included in the token, JWTs can be larger, especially if they carry lots of user information or metadata.
  • Sessions: Only the session ID is sent with each request, so the data transfer is minimal.

- Usage:

  • JWT: Preferred in modern, stateless APIs, single-page applications (SPAs), and mobile apps.
  • Sessions: Common in traditional web applications where the server manages user state.

2. JWT Authentication vs. Auth Tokens

Auth Tokens:
In token-based authentication (like Django’s built-in Token Authentication), the server generates a unique token when the user logs in. This token is stored on the server and sent to the client, which includes it in every request. The server checks the token in the database to verify the user.

Real-World Scenario:

API Access: An API provider (like GitHub) generates an API token for users after logging in. Every time you interact with the GitHub API, the token is passed in the request headers to authenticate the request.

JWT vs. Auth Tokens:

- Token Storage

JWT (JSON Web Token):

Stateless: JWTs are self-contained, meaning all the necessary information (claims) is stored within the token itself. The server doesn’t store the token, which makes it a stateless system.
The token is usually stored on the client-side (e.g., in localStorage, sessionStorage, or cookies) and sent with every request in the Authorization header.

Auth Tokens:

Stateful: In traditional token-based authentication, the token is generated and stored on the server side (often in a database). The server keeps track of the token, and the client includes it in each request (typically in the headers).

- Token Structure

JWT:

Self-Contained: JWT tokens consist of three parts: header, payload, and signature. The payload contains user information (like id, email, role) and is signed to ensure integrity.

Auth Tokens:

Opaque Tokens: Auth tokens are typically opaque strings, meaning they don’t carry any user information. They act as a reference to the server-side session or user data.
The server uses this token to look up the session or user information stored on the server.

- Server Storage and Scalability

JWT:

No Server Storage: Since JWT tokens are self-contained, the server doesn’t need to store session or token data. This makes it highly scalable, especially in distributed systems or microservices architectures, where multiple servers may be involved.

Auth Tokens:

Server-Side Storage: Auth tokens are stored in a database or memory on the server, which means the server must track and validate the token for each request. This can be less scalable since the server needs to access a central session store for every request.

- Security Considerations

JWT:

Signature-Based: JWT tokens are signed using algorithms like HS256 or RS256 to ensure the token hasn't been tampered with. While this protects the integrity of the token, it does not encrypt the data. Sensitive data shouldn't be included in the payload unless encrypted.

Client-Side Risks: JWTs are often stored in localStorage or sessionStorage, which can make them vulnerable to XSS (Cross-Site Scripting) attacks. To mitigate this, they can be stored in HTTP-only cookies.

Auth Tokens:

Server-Side Validation: Since auth tokens don’t contain user information and are validated against a session on the server, they can be considered safer from tampering. However, they are vulnerable to session hijacking or CSRF (Cross-Site Request Forgery) attacks if not handled properly.

- Expiration and Token Lifespan

JWT:

Short-Lived Access Tokens: JWTs typically have a short lifespan (e.g., 5–15 minutes). Once expired, the client must use a refresh token to get a new access token. This is a key part of JWT’s security model.
Refresh Tokens: Long-lived refresh tokens allow users to stay logged in without constantly re-entering credentials, but they also come with their own security challenges (e.g., they should be securely stored and managed).

Auth Tokens:

No Token Expiration by Default: Auth tokens don’t expire by default unless explicitly handled by the server. The server can revoke or expire tokens, but this requires additional logic and storage to track the tokens’ expiration.

- Token Size

JWT:

Larger Token Size: Since JWTs contain user information (claims) and the signature, they tend to be larger compared to opaque auth tokens. This can slightly increase bandwidth usage, especially in scenarios with frequent requests.

Auth Tokens:

Smaller Token Size: Auth tokens are usually opaque strings, meaning they are much smaller in size. They act as an identifier and don’t carry additional data, so they use less bandwidth.

- Example Usage Scenarios

JWT:

Single Page Applications (SPAs): JWTs work well with SPAs (like React or Angular) where you need stateless authentication and no server-side session management.

Microservices & APIs: JWTs are ideal for APIs and microservice architectures, where multiple services need to authenticate users without sharing session state across servers.
Auth Tokens:

Traditional Web Apps: In server-rendered web applications, auth tokens (or sessions) are commonly used, as they are stored and validated server-side, making them a good fit for applications where maintaining a session is easy.
Small-Scale Applications: Auth tokens work well for applications with fewer users, where session management doesn’t become a scalability issue.

- Statelessness vs. Statefulness

JWT:

Stateless: Since JWTs don’t require server-side storage, they make applications stateless. This is beneficial for scaling horizontally across multiple servers because there’s no need for session synchronization between servers.
Auth Tokens:

Stateful: Auth tokens require server-side session storage, meaning the server keeps track of the session data. This is fine for small applications but can be problematic when scaling to multiple servers unless a central session store (like Redis) is used.

- Blacklisting and Revocation

JWT:

Difficult to Revoke: Since JWTs are stateless and not stored on the server, it’s difficult to revoke them once issued unless you’re using token blacklisting. This means if a token is compromised, it remains valid until it expires.

Blacklisting Required: To handle token revocation (e.g., on logout), a blacklist mechanism must be implemented on the server to track invalidated tokens.

Auth Tokens:

Easy to Revoke: Auth tokens are stored on the server, so revoking or invalidating them is straightforward.

3. JWT Authentication vs. Basic Authentication

Basic Authentication:
In basic authentication, the client sends the user’s credentials (username and password) with every request, typically encoded in base64. This method is often used in internal systems or simple setups.

Real-World Scenario:

Internal Admin Dashboard: A small company’s internal admin dashboard requires users to log in with basic authentication. When users access a page, their credentials are sent in the request.

Real-World Use Case: When to Use JWT?

Let’s consider a real-world example: a social media platform where users log in, interact with posts, and manage their profiles across multiple devices.

In such a system:

  1. JWT works well because it is stateless, meaning the server doesn’t need to store user sessions.
  2. The client can store the token locally, which allows users to stay logged in across different tabs and devices.
  3. Since the app may scale horizontally across multiple servers (for example, one server for handling posts, and another for profiles), using JWT makes it easier to scale without needing a central session store.
  4. Users can also refresh their tokens periodically to maintain access without having to log in again.

Conclusion: Which Authentication Method to Choose?

Choosing the right authentication method depends on your application’s requirements:

JWT is ideal for stateless, scalable applications (like SPAs, mobile apps, and microservices).
Session-based authentication works well for traditional web applications where scalability is not a major concern.
Auth tokens are a simple, secure method for small-scale API authentication where server-side token storage is manageable.

Each method has its strengths and weaknesses, but JWT stands out for its ability to handle modern, distributed systems where scalability and flexibility are key.

. . .
Terabox Video Player