building-secure-apis-with-fastapi-and-oauth2-authentication.html

Building Secure APIs with FastAPI and OAuth2 Authentication

In today's digital landscape, securing APIs is more important than ever. With the rise of microservices and cloud-based applications, it's vital to ensure that your APIs are not only functional but also safe from unauthorized access. FastAPI, a modern web framework for building APIs with Python, offers a powerful way to create secure applications by leveraging OAuth2 authentication. In this article, we will explore how to build secure APIs using FastAPI and OAuth2, providing you with actionable insights, code examples, and best practices.

What is FastAPI?

FastAPI is a high-performance web framework for building APIs with Python 3.6+ based on standard Python type hints. It is designed to be easy to use, fast, and efficient, making it an ideal choice for developing secure APIs. FastAPI automatically generates OpenAPI and JSON Schema documentation, which is a huge time-saver during the development process.

Key Features of FastAPI

  • Asynchronous support: Built on Starlette, FastAPI supports asynchronous programming, allowing for better performance in handling multiple requests.
  • Automatic validation: FastAPI uses Python type hints for automatic request data validation.
  • OpenAPI and JSON Schema generation: Documentation is generated automatically, which makes it easy to understand and interact with your API.

What is OAuth2?

OAuth2 is an authorization framework that allows third-party applications to obtain limited access to a user's resources without exposing their credentials. It is widely used in modern web applications to secure APIs. OAuth2 provides different flows, including:

  • Authorization Code Flow: Best for server-side applications.
  • Implicit Flow: Suitable for client-side applications.
  • Resource Owner Password Credentials Flow: Useful for trusted applications.
  • Client Credentials Flow: Ideal for machine-to-machine communication.

Use Cases for OAuth2

  • Social media logins: Allow users to log in using their Facebook, Google, or Twitter accounts.
  • Third-party integrations: Enable other applications to access your API securely.
  • Mobile applications: Secure API access for mobile apps requiring user authentication.

Setting Up FastAPI with OAuth2

Let’s dive into a step-by-step guide on how to implement OAuth2 authentication in a FastAPI application.

Step 1: Install Required Packages

Start by installing FastAPI and an ASGI server, such as Uvicorn, using pip:

pip install fastapi uvicorn python-jose[cryptography] passlib[bcrypt]
  • python-jose: A library to handle JWT (JSON Web Tokens).
  • passlib: A library for password hashing.

Step 2: Create a Basic FastAPI App

Create a new Python file, main.py, and set up a basic FastAPI application.

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

Step 3: Implement OAuth2 Password Flow

Now, let’s implement the OAuth2 Password Flow. This will involve creating endpoints for user registration and token generation.

Setting Up User Models

First, define a user model and a mock database for storing user data.

from pydantic import BaseModel
from typing import Optional
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

class User(BaseModel):
    username: str
    email: Optional[str] = None
    full_name: Optional[str] = None

class UserInDB(User):
    hashed_password: str

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "$2b$12$KIX/1O4hM9gdjX2V1y6I6uHr9B4uWl3s8E1bUo7zjZ0Y4f6k1jB8e",  # bcrypt hashed version of 'password'
    }
}

Generating Password Hashes

Next, add utility functions to verify passwords and create access tokens.

from passlib.context import CryptContext
from datetime import datetime, timedelta
from jose import JWTError, jwt

SECRET_KEY = "your_secret_key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password):
    return pwd_context.hash(password)

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

Creating the Token Endpoint

Add an endpoint to handle the login and token generation.

@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user = fake_users_db.get(form_data.username)
    if not user or not verify_password(form_data.password, user['hashed_password']):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    # Create token
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(data={"sub": user['username']}, expires_delta=access_token_expires)
    return {"access_token": access_token, "token_type": "bearer"}

Step 4: Protecting Routes

Now, let’s protect some routes using the Depends function with the oauth2_scheme.

@app.get("/users/me")
async def read_users_me(token: str = Depends(oauth2_scheme)):
    # Token verification logic would go here
    return {"token": token}

Step 5: Running the Application

Run your FastAPI application using Uvicorn:

uvicorn main:app --reload

Now, you can access your API at http://127.0.0.1:8000/docs to see the automatically generated documentation.

Conclusion

Building secure APIs with FastAPI and OAuth2 is a robust way to ensure your applications are protected against unauthorized access. By following the steps outlined in this article, you can quickly implement OAuth2 authentication in your FastAPI application. Remember to keep your dependencies updated and follow security best practices to maintain the integrity of your API. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.