FastAPI Training: Authentication and Authorization
Key Concepts
Authentication and Authorization are critical components of securing your FastAPI application. Here are the key concepts:
- Authentication: The process of verifying the identity of a user.
- Authorization: The process of determining what actions a user is allowed to perform after they have been authenticated.
- JWT (JSON Web Tokens): A method for securely transmitting information between parties as a JSON object.
- OAuth2: An authorization framework that enables applications to obtain limited access to user accounts.
Authentication
Authentication is the process of verifying who a user is. In FastAPI, this is often done using JWT tokens. When a user logs in, the server generates a JWT token that contains information about the user. This token is then sent back to the client and included in the headers of subsequent requests.
Example of generating a JWT token:
from fastapi import FastAPI, Depends, HTTPException from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jose import JWTError, jwt from passlib.context import CryptContext app = FastAPI() SECRET_KEY = "your-secret-key" ALGORITHM = "HS256" oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @app.post("/token") async def login(form_data: OAuth2PasswordRequestForm = Depends()): user = authenticate_user(form_data.username, form_data.password) if not user: raise HTTPException(status_code=400, detail="Incorrect username or password") access_token = create_access_token(data={"sub": user.username}) return {"access_token": access_token, "token_type": "bearer"} def create_access_token(data: dict): to_encode = data.copy() encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) return encoded_jwt
Authorization
Authorization is the process of determining what actions a user is allowed to perform after they have been authenticated. In FastAPI, this is often done by checking the roles or permissions associated with the user.
Example of checking user roles:
from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from jose import JWTError, jwt oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") def get_current_user(token: str = Depends(oauth2_scheme)): credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username: str = payload.get("sub") if username is None: raise credentials_exception except JWTError: raise credentials_exception user = get_user(username) if user is None: raise credentials_exception return user @app.get("/users/me") async def read_users_me(current_user: User = Depends(get_current_user)): return current_user
JWT (JSON Web Tokens)
JWT is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.
Example of decoding a JWT token:
from jose import JWTError, jwt def decode_token(token: str): try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) return payload except JWTError: return None
OAuth2
OAuth2 is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service, such as Facebook, GitHub, and DigitalOcean. It works by delegating user authentication to the service that hosts the user account, and authorizing third-party applications to access the user account.
Example of using OAuth2 with FastAPI:
from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @app.post("/token") async def login(form_data: OAuth2PasswordRequestForm = Depends()): user = authenticate_user(form_data.username, form_data.password) if not user: raise HTTPException(status_code=400, detail="Incorrect username or password") access_token = create_access_token(data={"sub": user.username}) return {"access_token": access_token, "token_type": "bearer"}
Analogies
Think of Authentication as checking someone's ID at the entrance of a building. Once their identity is verified, Authorization is like checking their access card to see which rooms they are allowed to enter. JWT is like a digital access card that contains all the necessary information, and OAuth2 is like a security system that allows external services to access certain parts of the building on behalf of the user.
By understanding these concepts, you can effectively secure your FastAPI application and ensure that only authorized users can perform specific actions.