User Registration, Login and Security

Chapter 7
6 min read
110 reads

In this tutorial we''re going to create an authentication system. We want to build our website, however, we don't want unauthenticated users to access the dashboard screen.

We will build our backend with Fast API, our Frontend with NextJS and the database will be SQLITE3.

Step 1: Set up the backend

Create your project folder and set up the FastAPI backend.

mkdir auth-project && cd auth-project
mkdir backend && cd backend
python -m venv venv
source venv/bin/activate  # on Windows: venv\Scripts\activate

Our backend needs external libraries for it to function fully. Inside the backend folder, create a file named requiremnts.txt and put the contents below inside:

fastapi==0.135.2
uvicorn==0.42.0
pydantic==2.12.5
passlib==1.7.4
bcrypt==4.0.1
python-jose==3.5.0
cryptography==46.0.6
python-multipart==0.0.22
starlette==1.0.0

So here, we've just defined our packages/dependencies/libraries. The next step is to install them into our environment. Run the command below in the terminal:

pip install -r requirements.txt

Inside the backend folder, create a main.py file:

from fastapi import HTTPException,FastAPI,  Depends, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
from passlib.context import CryptContext
from jose import JWTError, jwt
from datetime import datetime, timedelta
import sqlite3
app = FastAPI()
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
SECRET_KEY = "your-secret-key-change-this"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_c CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")
# --- Database setup ---
def get_db():
    c sqlite3.connect("users.db")
    conn.row_factory = sqlite3.Row
    return conn
def init_db():
    c get_db()
    conn.execute("""
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT NOT NULL,
            email TEXT UNIQUE NOT NULL,
            hashed_password TEXT NOT NULL
        )
    """)
    conn.commit()
    conn.close()
init_db()
# --- Schemas ---
class RegisterSchema(BaseModel):
    username: str
    email: str
    password: str
class LoginSchema(BaseModel):
    email: str
    password: str
# --- Helpers ---
def hash_password(password: str):
    return pwd_context.hash(password)
def verify_password(plain: str, hashed: str):
    return pwd_context.verify(plain, hashed)
def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
# --- Routes ---
@app.get("/")
def read_root():
    return {"Hello": "API is up and Running"}
@app.post("/register")
def register(user: RegisterSchema):
    c get_db()

existing = conn.execute("SELECT * FROM users WHERE email = ?", (user.email,)).fetchone()

Want to support this author?

By unlocking the full story, you directly support local writers. You'll also be able to track your reads, and discover amazing content!

User Registration, Login and Security - SELF TAUGHT COMPUTER SCIENCE | Soma