Skip to content

Token Authentication

Code

.
├── api
│   ├── __init__.py
│   ├── items.py
│   └── users.py
├── config.py
├── dependencies.py
├── __init__.py
├── main.py
└── models.py
app/__init__.py

app/config.py
# Don't do this in production, read this token from an environment variable
secret_token = "supersecret"
app/dependencies.py
import secrets

from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer

from .config import secret_token

bearer_scheme = HTTPBearer()


def authenticate_token(
    credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme),
) -> str:
    if not secrets.compare_digest(credentials.credentials, secret_token):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials"
        )
    return credentials.credentials
app/main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from .api import items, users

app = FastAPI()

origins = [
    "http://localhost.tiangolo.com",
    "https://localhost.tiangolo.com",
    "http://localhost",
    "http://localhost:8080",
    "https://fastapiworkshop.yaquelinehoyos.com",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


app.include_router(users.router)
app.include_router(items.router)
app/models.py
from typing import Optional

from pydantic import BaseModel


class Item(BaseModel):
    title: str
    description: Optional[str] = None


class User(BaseModel):
    username: str
app/api/__init__.py

app/api/users.py
from fastapi import APIRouter, Depends

from ..dependencies import authenticate_token
from ..models import User

router = APIRouter()


@router.post(
    "/users/",
    dependencies=[Depends(authenticate_token)],
)
def create_user(user: User):
    return user


@router.get("/users/")
def read_users():
    return [{"username": "Rick"}, {"username": "Morty"}]


@router.get("/users/{user_id}")
def read_user(user_id: int):
    return {"id": user_id, "username": "Pickle Rick"}
app/api/items.py
from fastapi import APIRouter, Depends

from ..dependencies import authenticate_token
from ..models import Item

router = APIRouter()


@router.post(
    "/users/{user_id}/items/",
    dependencies=[Depends(authenticate_token)],
)
def create_item_for_user(user_id: int, item: Item):
    return item


@router.get("/items/")
def read_items():
    return [
        {"title": "Portal Gun", "description": "A gun that shoots portals"},
        {"title": "Towel"},
    ]

Server

Run the live server:

$ uvicorn app.main:app --reload

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<span style="color: green;">INFO</span>:     Started reloader process [28720]
<span style="color: green;">INFO</span>:     Started server process [28722]
<span style="color: green;">INFO</span>:     Waiting for application startup.
<span style="color: green;">INFO</span>:     Application startup complete.

API docs

Now you can open the API docs UI at: http://127.0.0.1:8000/docs.

Admin Dashboard

You can go to the admin dashboard (created for this workshop) to interact with your API: https://fastapiworkshop.yaquelinehoyos.com.