Cookies in web apps

Cookies in Web Applications

Cookies are small pieces of data that a server sends to a user's browser. They are stored on the user's device and sent back to the server with subsequent requests. Cookies are primarily used to maintain stateful information between HTTP requests, which are otherwise stateless by nature.

Key Concepts of Cookies:

What is a Cookie?

Structure of a Cookie:

A cookie consists of the following components:

Types of Cookies:

Client-Side Cookies:

Example (Setting a cookie with JavaScript):

document.cookie = "username=Ash; expires=Thu, 18 Dec 2024 12:00:00 UTC; path=/";

Server-Side Cookies:

Example (Setting a cookie in an HTTP response):

Set-Cookie: session_id=abc123; HttpOnly; Secure; Path=/; Expires=Wed, 13 Oct 2024 07:28:00 GMT

Difference Between Client-Side and Server-Side Cookies

Type Who Sets It? Who Can Access It? Example Use Case Security Considerations
Client-Side Client (Browser) Client (JavaScript), unless HttpOnly Storing user preferences Vulnerable to XSS unless HttpOnly
Server-Side Server Server (via HTTP headers), sometimes Client Session management, authentication Use HttpOnly, Secure flags for security

Common Use Cases of Cookies:

Example: Server-Side Cookie Flow

  1. User logs into a website.
  2. The server authenticates the user and generates a session ID cookie.
  3. The server sends the session ID cookie to the client using the Set-Cookie header in the response.
  4. The browser stores this cookie.
  5. For each subsequent request, the browser automatically sends the session ID cookie to the server.
  6. The server identifies the user based on the session ID and maintains the user's login state.

Security Concerns:

Summary:

Type Who Sets It? Who Can Access It? Example Use Case Security Considerations
Client-Side Client (Browser) Client (JavaScript), unless HttpOnly Storing user preferences Vulnerable to XSS unless HttpOnly
Server-Side Server Server (via HTTP headers), sometimes Client Session management, authentication Use HttpOnly, Secure flags for security

Cookies in JavaScript and FastAPI

Cookies in JavaScript

Cookies are a key way to store data client-side in web browsers. In JavaScript, you can set, retrieve, and delete cookies to manage information like session identifiers or user preferences.

Setting Cookies with JavaScript

Cookies are set using the document.cookie API. You can specify a key-value pair along with several attributes such as expires, path, domain, etc.

Example: Setting a Cookie in JavaScript

// Set a cookie that expires in one day
const date = new Date();
date.setTime(date.getTime() + (24 * 60 * 60 * 1000)); // 1 day in milliseconds
const expires = "expires=" + date.toUTCString();
document.cookie = "username=Ash; " + expires + "; path=/";

Reading Cookies in JavaScript

You can read cookies using document.cookie, which returns all cookies as a single string. You can split this string into individual cookies and access the values.

Example: Reading a Cookie

function getCookie(name) {
    let decodedCookie = decodeURIComponent(document.cookie);
    let cookiesArray = decodedCookie.split(';');
    for (let cookie of cookiesArray) {
        while (cookie.charAt(0) === ' ') {
            cookie = cookie.substring(1);
        }
        if (cookie.indexOf(name + "=") === 0) {
            return cookie.substring(name.length + 1, cookie.length);
        }
    }
    return "";
}

// Retrieve the 'username' cookie
let username = getCookie("username");
console.log(username); // Outputs: Ash

Deleting Cookies in JavaScript

To delete a cookie, set its expires attribute to a past date:

document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";

Cookies in FastAPI

FastAPI makes working with cookies on the server-side straightforward. You can set cookies in responses, read them from requests, and configure security settings such as HttpOnly, Secure, and SameSite.

Setting Cookies in FastAPI

You can use the set_cookie() method in a FastAPI route to add a cookie to the response.

Example: Setting a Cookie in FastAPI

from fastapi import FastAPI, Response

app = FastAPI()

@app.get("/set-cookie/")
def set_cookie(response: Response):
    response.set_cookie(
        key="session_id",
        value="abc123",
        httponly=True,  # HttpOnly cookies are inaccessible to JavaScript
        secure=True,    # Secure cookies are only sent over HTTPS
        samesite="lax", # Helps prevent cross-site request forgery (CSRF)
        max_age=3600,   # Expires in 1 hour
    )
    return {"message": "Cookie set successfully"}

Reading Cookies in FastAPI

You can retrieve cookies using the Cookie dependency in FastAPI.

Example: Reading a Cookie in FastAPI

from fastapi import FastAPI, Cookie

app = FastAPI()

@app.get("/read-cookie/")
def read_cookie(session_id: str = Cookie(None)):
    if session_id:
        return {"session_id": session_id}
    return {"error": "No session_id cookie found"}

Deleting Cookies in FastAPI

You can delete cookies by setting their expiration to a past date using the delete_cookie() method:

@app.get("/delete-cookie/")
def delete_cookie(response: Response):
    response.delete_cookie(key="session_id")
    return {"message": "Cookie deleted"}

Full Cookie Configuration in FastAPI

FastAPI provides several options for customizing cookies, including:

Example: Custom Cookie Settings

@app.get("/set-custom-cookie/")
def set_custom_cookie(response: Response):
    response.set_cookie(
        key="custom_cookie",
        value="custom_value",
        httponly=True,
        secure=True,
        samesite="strict",  # Strict SameSite policy
        path="/custom-path",  # Available only on /custom-path
        domain="example.com",  # Available to the domain example.com
        max_age=7200,  # Expires in 2 hours
    )
    return {"message": "Custom cookie set with specific attributes"}

LocalStorage vs Cookies

When working with web applications, both LocalStorage and Cookies are used to store data on the client-side. However, they have significant differences in terms of capacity, accessibility, security, and use cases.

1. Storage Capacity

Summary: LocalStorage offers much larger storage capacity compared to cookies.

2. Expiration

Summary: LocalStorage persists indefinitely, while cookies can expire based on server-side settings.

3. Accessibility

Summary: LocalStorage is only client-side, while cookies can be sent to the server automatically.

4. Security

Summary: Cookies offer better security features for sensitive data.

5. Automatic Server Transmission

Summary: Cookies are useful when you need to send data to the server automatically, like session management.

6. Use Cases

7. Read/Write Operations

Summary: LocalStorage is more efficient for frequent read/write operations.

8. Data Storage Scope

Summary: Cookies offer more control over where they are valid, while LocalStorage is available across the entire domain.

Comparison Table

Feature LocalStorage Cookies
Capacity 5-10MB 4KB
Expiration Persistent until manually cleared Can expire based on max-age or expires
Accessibility Client-side (JavaScript only) Accessible to both client-side and server-side
Security Vulnerable to XSS Can be secured with HttpOnly and Secure flags
Automatic Server Transmission Not automatically sent to server Automatically sent with every HTTP request
Use Cases Storing non-sensitive, client-side data Storing session data, authentication tokens
Data Scope Domain-wide Can be restricted to specific paths/domains

Conclusion