---
title: "💭 First-class session support in FastAPI · Issue #754 · tiangolo..."
description: "!https://github.com/tiangolo/fastapi/issues/754"
date: 2023-07-28
published: true
tags:
  - python
  - fastapi
  - security
  - thought
template: link
---


<div class="embed-card embed-card-external">
  <a href="https://github.com/tiangolo/fastapi/issues/754" class="embed-card-link" target="_blank" rel="noopener noreferrer">
    <div class="embed-card-image">
      <img src="https://opengraph.githubassets.com/5190baf4079f115873906d0710f7ee90869032b3ff4751df480a4ca41ff00084/fastapi/fastapi/issues/754" alt="First-class session support in FastAPI · Issue #754 · fastapi/fastapi — Is your feature request related to a problem All of the security schemas currently supported by FastAPI rely on some sort of &#34;client-server synergy&#34; , where, for instance, the client is expected to..." loading="lazy">
    </div>
    <div class="embed-card-content">
      <div class="embed-card-title">First-class session support in FastAPI · Issue #754 · fastapi/fastapi</div>
      <div class="embed-card-description">Is your feature request related to a problem All of the security schemas currently supported by FastAPI rely on some sort of &#34;client-server synergy&#34; , where, for instance, the client is expected to...</div>
      <div class="embed-card-meta">GitHub &middot; github.com</div>
    </div>
  </a>
</div>


Here is a snippet provided by @tiangolo to store the users jwt inside of a session cookie in fatapi.  This was written in feb 12, 2020 and admits that this is not a well documented part of fastapi.

> It's already in place. More or less like the rest of the security tools. And it's compatible with the rest of the parts, integrated with OpenAPI (as possible), but probably most importantly, with dependencies.

> It's just not properly documented yet. 😞

> But still, it works 🚀 e.g.

``` python
from fastapi import FastAPI, Form, HTTPException, Depends
from fastapi.security import APIKeyCookie
from starlette.responses import Response, HTMLResponse
from starlette import status
from jose import jwt


app = FastAPI()

cookie_sec = APIKeyCookie(name="session")

secret_key = "someactualsecret"

users = {"dmontagu": {"password": "secret1"}, "tiangolo": {"password": "secret2"}}


def get_current_user(session: str = Depends(cookie_sec)):
    try:
        payload = jwt.decode(session, secret_key)
        user = users[payload["sub"]]
        return user
    except Exception:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN, detail="Invalid authentication"
        )


@app.get("/login")
def login_page():
    return HTMLResponse(
        """
        <form action="/login" method="post">
        Username: <input type="text" name="username" required>
        <br>
        Password: <input type="password" name="password" required>
        <input type="submit" value="Login">
        </form>
        """
    )


@app.post("/login")
def login(response: Response, username: str = Form(...), password: str = Form(...)):
    if username not in users:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN, detail="Invalid user or password"
        )
    db_password = users[username]["password"]
    if not password == db_password:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN, detail="Invalid user or password"
        )
    token = jwt.encode({"sub": username}, secret_key)
    response.set_cookie("session", token)
    return {"ok": True}


@app.get("/private")
def read_private(username: str = Depends(get_current_user)):
    return {"username": username, "private": "get some private data"}
```



!!! note

    This post is a <a href="/thoughts/" class="wikilink" data-title="Thoughts" data-description="These are generally my thoughts on a web page or some sort of url, except a rare few don&#39;t have a link. These are dual published off of my..." data-date="2024-04-01">thought</a>. It's a short note that I make
    about someone else's content online <a href="/tags/thoughts/" class="hashtag-tag" data-tag="thoughts" data-count=2 data-reading-time=3 data-reading-time-text="3 minutes">#thoughts</a>
