fastapi搭建平台实战教程二:快速实现用户注册和登录

这一篇主要实现用户注册和登录

编写接口并设置URL

main.py添加注册表单参数和简单注册接口

复制代码
from fastapi import FastAPI
from pydantic import BaseModel

import models
from db import engine, SessionLocal
from fastapi.responses import JSONResponse


models.Base.metadata.create_all(bind=engine)

app = FastAPI()


class RegisterForm(BaseModel):
    username: str
    password: str

@app.post("/register")
def register(user: RegisterForm):
    if SessionLocal().query(models.User).filter_by(username=user.username).count() > 0:
        return JSONResponse({
            "code": 400,
            "msg": "用户已存在"
        })
    db_user = models.User(username=user.username, password=user.password)
    with SessionLocal.begin() as session:
        session.add(db_user)
    return JSONResponse({
            "code": 0,
            "msg": "注册成功"
        })
复制代码

添加登录表单参数,编写简单登录接口

复制代码
class LoginForm(BaseModel):
    username: str
    password: str

@app.post("/login")
def login(user:LoginForm):
    user = SessionLocal().query(models.User).filter_by(username = user.username).first()
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    response = JSONResponse({
            "code": 0,
            "msg": "登录成功"
        })
    return response
复制代码

之后使用JWT令牌(Token)和安全密码哈希(Hash)实现真正的安全机制

安装 python-jose和PassLib

pip install python-jose

pip install passlib

pip install bcrypt

编写auth.py,加入三个方法,分别是加密密码,校验加密密码,生成token

复制代码
from jose import jwt
from passlib.context import CryptContext

SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
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)

def create_access_token(data: dict):
    to_encode = data.copy()
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt
复制代码

注册登录接口加上这些功能

复制代码
@app.post("/register")
def register(user: RegisterForm):
    if SessionLocal().query(models.User).filter_by(username=user.username).count() > 0:
        return JSONResponse({
            "code": 400,
            "msg": "用户已存在"
        })
    db_user = models.User(username=user.username, password=get_password_hash(user.password))
    with SessionLocal.begin() as session:
        session.add(db_user)
    return JSONResponse({
            "code": 0,
            "msg": "注册成功"
        })

class LoginForm(BaseModel):
    username: str
    password: str

@app.post("/login")
def login(form:LoginForm):
    user = SessionLocal().query(models.User).filter_by(username = form.username).first()
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    if not verify_password(form.password, user.password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token = create_access_token(
        data={"sub": user.username}
    )
    response = JSONResponse({
            "code": 0,
            "msg": "登录成功",
            "access_token": access_token
        })
    return response
复制代码

auth.py编写通过JWTtoken获取当前用户

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

def get_current_user(token: str = Depends(oauth2_scheme)):
    payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
    username: str = payload.get("sub")
    user = SessionLocal().query(models.User).filter_by(username = username).first()
    return user

新增用户信息接口验证逻辑

复制代码
class UserRes(BaseModel):
    username: str
    nickname: str | None = None
    email: str | None = None
    isadmin: bool | None = False

@app.get("/users/info", response_model=UserRes)
async def read_users_me(current_user: UserRes = Depends(get_current_user)):
    return current_user
复制代码

 这样用户的注册和登录基本实现,可以进行更多后端接口逻辑的编写了。

 

 

posted @   紧肛胡撸娃  阅读(2641)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示