JWT Authentication in FastAPI

Git Commit: JWT token creation
Good Resources:

We are going to authenticate our users using JSON web tokens, In API first approach we mostly see jwt-based authentication. In simple words, we supply our email and password once to the API and the API  responds back with a long string/token which we provide to log in. Just like everything else, It comes with pros and cons. One of the main advantages is, even if the token is stolen, our user's account is not compromised permanently, because these tokens are normally valid for a few hours/days based on a parameter called expiry.
In this post, we are going to learn to create an access token, given an email or a username. We need to create a new file inside the core folder. core > security.py and put the following code here.

from datetime import datetime,timedelta
from typing import Optional
from jose import jwt

from core.config import settings


def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
    return encoded_jwt
  • We will be receiving a data dictionary with a subject (sub). This sub is ideally an email/username that can uniquely identify each record in the table.
  • data dict. might look like {"sub":"[email protected]"}
  • These access tokens will auto-expire in 30 minutes.
  • We make use of a secret key and algorithms to encode this data dictionary to get a dedicated access token.

For creating an access token we also need a secret_key and the name of the algorithm to be used. So, let's add these in our core > config.py file

import os
from dotenv import load_dotenv

from pathlib import Path
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)

class Settings:
    PROJECT_NAME: str = "Algoholic 🔥"
    PROJECT_VERSION: str = "1.0.0"
    
    ....
    ....
    DATABASE_URL = f"postgresql://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_SERVER}:{POSTGRES_PORT}/{POSTGRES_DB}"

    SECRET_KEY :str = os.getenv("SECRET_KEY")   #new
    ALGORITHM = "HS256"                         #new
    ACCESS_TOKEN_EXPIRE_MINUTES = 30  #in mins  #new

settings = Settings()

Since we are getting the secret key from the environment variable, we need to make this environment variable or we can also add a secret key to our .env file. I am making an extra file .env.template to remind you that you need to have a .env file.

POSTGRES_USER=postgres
POSTGRES_PASSWORD=yourpasswordhere
POSTGRES_SERVER=localhost
POSTGRES_PORT=5432
POSTGRES_DB=yourdbname
SECRET_KEY=supersecretkeyhere!!  #new

We are using python-jose to create access tokens, we may also use python jwt library but python-jose is updated and a kind of superset of python-jwt. So, let's stick to python-jose only. Let's add this requirement in the requirements.txt file and do a pip install.

fastapi==0.95.1
###
python-jose==3.3.0

All done, time to test whether it works or not, Let's test it in cmd/terminal.

FastAPITutorial

Brige the gap between Tutorial hell and Industry. We want to bring in the culture of Clean Code, Test Driven Development.

We know, we might make it hard for you but definitely worth the efforts.

Contacts

Refunds:

Refund Policy
Social

Follow us on our social media channels to stay updated.

© Copyright 2022-23 Team FastAPITutorial