Henry Hoang

note

note

FastAPI Advanced Topics: Authentication, Authorization, and Testing

1. Introduction

  • Overview of what we’ll cover:
    • OAuth2 with JWT
    • Password hashing
    • get_current_user dependency
    • Role-Based Access Control (RBAC)
    • Testing with Pytest and TestClient
    • CORS configuration
    • Async dependencies for efficiency

2. Authentication with OAuth2 and JWT

  • OAuth2 Password Flow:

    • Explain why OAuth2 is used for token-based authentication.
    • Show how to use OAuth2PasswordBearer in FastAPI.
  • JWT (JSON Web Tokens):

    • Structure of JWT: Header, Payload, Signature.
    • Why JWT is stateless and efficient.
  • Implementation Steps:

    • Install python-jose for JWT signing.
    • Create utility functions:
      • create_access_token(data: dict, expires_delta: timedelta)
      • verify_token(token: str)
  • Async Example:

    from fastapi.security import OAuth2PasswordBearer
    from jose import JWTError, jwt
    
    oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
    
    async def get_current_user(token: str = Depends(oauth2_scheme)):
        try:
            payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
            username: str = payload.get("sub")
            if username is None:
                raise credentials_exception
            return username
        except JWTError:
            raise credentials_exception

3. Password Hashing

  • Use passlib or bcrypt for secure hashing.

  • Explain why hashing is critical (never store plain passwords).

  • Example:

    from passlib.context import CryptContext
    
    pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
    
    def hash_password(password: str):
        return pwd_context.hash(password)
    
    def verify_password(plain_password: str, hashed_password: str):
        return pwd_context.verify(plain_password, hashed_password)

4. Role-Based Access Control (RBAC)

  • Define roles: admin, user, etc.
  • Implement a dependency that checks roles:
    async def require_role(role: str):
        async def role_checker(current_user = Depends(get_current_user)):
            if current_user.role != role:
                raise HTTPException(status_code=403, detail="Not enough permissions")
        return role_checker
  • Usage:
    @app.get("/admin")
    async def admin_dashboard(role_check = Depends(require_role("admin"))):
        return {"msg": "Welcome Admin"}

5. CORS Configuration

  • Why CORS matters for frontend-backend communication.

  • Example:

    from fastapi.middleware.cors import CORSMiddleware
    
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],  # or specific domains
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

6. Testing with Pytest and TestClient

  • Install pytest and httpx (or use FastAPI’s TestClient).

  • Example test:

    from fastapi.testclient import TestClient
    from main import app
    
    client = TestClient(app)
    
    def test_read_main():
        response = client.get("/")
        assert response.status_code == 200
        assert response.json() == {"msg": "Hello World"}
  • For async tests, use httpx.AsyncClient.


7. Emphasizing Async Dependencies

  • Explain why async def improves scalability.
  • Show how to make DB calls and external API calls async.
  • Example:
    async def get_db():
        async with async_session() as session:
            yield session

8. Putting It All Together

  • Build a small project:
    • /register → hash password and store user.
    • /login → issue JWT token.
    • /me → get current user.
    • /admin → RBAC check.
  • Include tests and CORS setup.

✅ Would you like me to create a full sample FastAPI project with all these features (OAuth2, JWT, hashing, RBAC, async DB, tests, and CORS) in a single codebase? Or should I prepare a slide deck outline for teaching these concepts?


On this page