You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在带JWT与bcrypt加密的FastAPI应用中创建首个用户

解决FastAPI应用首个用户创建问题的几种可行方案

方案一:给注册端点加环境变量控制的免认证逻辑

核心思路是让注册接口在初始化模式下跳过JWT认证,创建完首个用户后关闭该模式即可,完全不影响正式部署的安全性。

具体实现:

  1. 修改你的认证依赖函数,加入环境变量判断:
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
import os

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    # 检查是否开启初始化模式
    if os.getenv("INIT_MODE") == "true":
        return None  # 直接跳过认证
    # 以下是你原来的JWT认证逻辑
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="无法验证凭证",
        headers={"WWW-Authenticate": "Bearer"},
    )
    # ... 你的token解析、用户查询逻辑
  1. 注册端点保持原有逻辑,依赖这个修改后的认证函数即可:
from fastapi import APIRouter, Depends, HTTPException
from passlib.context import CryptContext
from sqlalchemy.orm import Session
from .database import get_db
from .schemas import UserCreate
from .models import User

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

@router.post("/users/")
async def create_user(
    user: UserCreate,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    # 检查邮箱是否已存在
    db_user = db.query(User).filter(User.email == user.email).first()
    if db_user:
        raise HTTPException(status_code=400, detail="邮箱已注册")
    # 用bcrypt加密密码(和你现有逻辑一致)
    hashed_password = pwd_context.hash(user.password)
    new_user = User(email=user.email, hashed_password=hashed_password)
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    return {"email": new_user.email}
  1. 部署时临时开启初始化模式:
    启动FastAPI容器时设置环境变量INIT_MODE=true:
docker run -e INIT_MODE=true -d --name fastapi-app --link postgres-db:postgres your-fastapi-image

用curl或Postman调用/users/接口创建首个用户后,再重启容器去掉这个环境变量即可。

方案二:写独立的初始化脚本直接操作数据库

不需要启动FastAPI应用,直接写个Python脚本连接数据库,用bcrypt加密密码后插入首个用户,适合自动化部署场景。

脚本示例(init_admin.py):

import os
import bcrypt
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# 导入你项目中的User模型
from your_project.models import User

# 数据库连接地址,可通过环境变量传入
DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://db_user:db_pass@postgres-db:5432/db_name")

engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

def create_admin():
    db = SessionLocal()
    # 先检查是否已有管理员用户
    admin = db.query(User).filter(User.email == "admin@yourdomain.com").first()
    if not admin:
        # 加密密码
        raw_pwd = "your_admin_password"
        hashed_pwd = bcrypt.hashpw(raw_pwd.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
        new_admin = User(email="admin@yourdomain.com", hashed_password=hashed_pwd)
        db.add(new_admin)
        db.commit()
        print("管理员用户创建成功")
    else:
        print("管理员用户已存在")
    db.close()

if __name__ == "__main__":
    create_admin()

运行脚本:
把脚本放到项目目录,用容器运行(确保能连接到数据库容器):

docker run --rm --link postgres-db:postgres -v $(pwd):/app your-fastapi-image python /app/init_admin.py

方案三:Docker Compose中添加初始化服务

如果用Docker Compose部署,可以加一个一次性的初始化服务,自动在启动时创建首个用户,完成后自动退出。

修改docker-compose.yml:

version: '3.8'
services:
  postgres:
    image: postgres:15
    environment:
      POSTGRES_USER: db_user
      POSTGRES_PASSWORD: db_pass
      POSTGRES_DB: db_name
    volumes:
      - postgres_data:/var/lib/postgresql/data/

  fastapi-app:
    build: .
    environment:
      DATABASE_URL: postgresql://db_user:db_pass@postgres:5432/db_name
    ports:
      - "8000:8000"
    depends_on:
      - postgres
      - init-admin

  init-admin:
    build: .
    environment:
      DATABASE_URL: postgresql://db_user:db_pass@postgres:5432/db_name
    command: python /app/init_admin.py
    depends_on:
      - postgres
    restart: on-failure  # 确保数据库启动完成后再执行
volumes:
  postgres_data:

执行docker-compose up时,init-admin服务会先运行脚本创建用户,之后自动退出,不会影响后续服务运行。

内容的提问来源于stack exchange,提问作者Diegol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:35:19