2-how-to-set-up-a-secure-api-using-fastapi-and-oauth-20.html

How to Set Up a Secure API Using FastAPI and OAuth 2.0

In today’s digital landscape, building secure APIs is paramount. With the increasing reliance on web services and mobile applications, ensuring that your API is protected against unauthorized access is crucial. FastAPI, a modern and fast web framework for building APIs with Python, simplifies this process significantly. In this article, we’ll explore how to set up a secure API using FastAPI and OAuth 2.0, a widely used authorization framework.

What is FastAPI?

FastAPI is an asynchronous web framework that allows developers to create APIs quickly and efficiently. Its key features include:

  • High performance: FastAPI is built on Starlette and Pydantic, making it one of the fastest frameworks available.
  • Ease of use: With automatic generation of interactive API documentation and a user-friendly syntax, FastAPI is accessible to developers of all skill levels.
  • Support for asynchronous programming: It natively supports asynchronous programming, which is essential for building scalable applications.

Understanding OAuth 2.0

OAuth 2.0 is an authorization framework that allows third-party applications to obtain limited access to user accounts on an HTTP service. It is widely used for securing APIs, enabling users to share their information without exposing their credentials. The main components of OAuth 2.0 include:

  • Resource Owner: The user who authorizes an application to access their account.
  • Client: The application wanting to access the user’s data.
  • Authorization Server: The server that validates credentials and issues access tokens.
  • Resource Server: The server hosting the user’s data.

Use Cases for FastAPI and OAuth 2.0

  1. Microservices Architecture: FastAPI facilitates the development of microservices that need to authenticate users securely.
  2. Mobile Applications: When developing mobile apps, OAuth 2.0 allows users to log in with existing accounts (e.g., Google, Facebook) without needing to create new credentials.
  3. Third-Party Integrations: If you’re building an API that external applications will use, OAuth 2.0 provides a standardized way to grant access securely.

Setting Up a Secure API with FastAPI and OAuth 2.0

Step 1: Install FastAPI and Required Libraries

Before we dive into the coding, let’s install FastAPI and other necessary libraries. You’ll also need an ASGI server like uvicorn to run your application.

pip install fastapi uvicorn python-jose[cryptography] passlib[bcrypt]

Step 2: Create the FastAPI Application

Now, let’s create a simple FastAPI application. Start by creating a new Python file, main.py.

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel
from typing import Optional
from datetime import datetime, timedelta
import jwt

app = FastAPI()

# Secret key for encoding/decoding JWT
SECRET_KEY = "your_secret_key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

Step 3: Define User Models

Next, let’s define the user model and create a mock database for demonstration purposes.

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

class UserInDB(User):
    hashed_password: str

# Mock database
fake_users_db = {
    "johndoe": UserInDB(
        username="johndoe",
        email="johndoe@example.com",
        full_name="John Doe",
        disabled=False,
        hashed_password="$2b$12$eW8LQZcF7bXg5KzqOeZzWuW95t5B/LQvO7cQ1N9G9fQ1LhTtH1Z6m"  # hashed password for "password"
    )
}

Step 4: Create the Authentication Logic

Now, let’s implement the functions to verify users and create access tokens.

from passlib.context import CryptContext

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

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

def get_user(db, username: str):
    if username in db:
        return db[username]

def create_access_token(data: dict, expires_delta: timedelta = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

Step 5: Create the Login Endpoint

We need to create an endpoint that allows users to log in and receive a token.

@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user = get_user(fake_users_db, 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"},
        )
    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 6: Protecting Routes

To secure your API routes, use the oauth2_scheme to extract the token and validate it.

@app.get("/users/me")
async def read_users_me(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )

    # Here you would decode the token and verify its validity
    # For simplicity, this example does not include token validation logic
    return {"token": token}

Step 7: Running the Application

Now, run your FastAPI application using uvicorn.

uvicorn main:app --reload

Conclusion

In this article, we covered the essentials of setting up a secure API using FastAPI and OAuth 2.0. We explored the framework’s features, defined relevant concepts, and provided actionable coding insights. By following these steps, you can create a robust, secure API that adheres to modern authentication standards.

FastAPI not only streamlines the development process but also empowers developers to build high-performance APIs with ease. Whether you’re building a microservice or a comprehensive web application, leveraging FastAPI with OAuth 2.0 can significantly enhance your project’s security and user experience.

SR
Syed
Rizwan

About the Author

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