123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- from fastapi import APIRouter, Depends, HTTPException, status
- from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
- from pydantic import BaseModel
- from db.database import Base, engine, get_db
- from db.models import DbUsers
- from sqlalchemy.orm import Session
- from datetime import datetime, timedelta
- from jose import JWTError, jwt
- from typing import Optional
- from passlib.context import CryptContext
- from utils.response import resp_200, resp_400
- # JWT 相关配置
- SECRET_KEY = "kg-server"
- ALGORITHM = "HS256"
- ACCESS_TOKEN_EXPIRE_MINUTES = 30
- oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/token")
- pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
- password = "secret"
- hashed_password = pwd_context.hash(password)
- print("auth.py Hashed password:", hashed_password)
- # 假的用户数据库
- # fake_users_db = {
- # "johndoe": {
- # "username": "johndoe",
- # "full_name": "John Doe",
- # "email": "johndoe@example.com",
- # "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36Y6QJwqmn4yZHRx70jN9nF", # 密码为 'secret'
- # "disabled": False,
- # }
- # }
- # 用户模型
- class Token(BaseModel):
- access_token: str
- token_type: str
- class User(BaseModel):
- username: str
- email: Optional[str] = None
- full_name: Optional[str] = None
- status: Optional[int] = None
- class UserInDB(User):
- hashed_password: str
- class Config:
- from_attributes = True
- # 密码验证
- 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 get_user(db, username: str):
- user = db.query(DbUsers).filter(DbUsers.username == username).first()
- if user:
- return UserInDB.model_validate(user)
- return None
- def authenticate_user(db, username: str, password: str):
- user = get_user(db, username)
- if not user:
- return False
- if not verify_password(password, user.hashed_password):
- return False
- return user
- # 创建访问令牌
- 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=15)
- to_encode.update({"exp": expire})
- encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
- return encoded_jwt
- # 路由
- router = APIRouter()
- @router.post("/api/token")
- async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
-
- user = authenticate_user(db, form_data.username, form_data.password)
- if not user:
- return resp_400(message="Incorrect username or password", data=[])
-
- access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
- access_token = create_access_token(
- data={"sub": user.username}, expires_delta=access_token_expires
- )
- return resp_200(data = {"access_token": access_token, "token_type": "bearer"})
- # 获取当前用户
- @router.get("/api/get-user")
- async def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):
- credentials_exception = HTTPException(
- status_code=status.HTTP_401_UNAUTHORIZED,
- detail="Could not validate credentials",
- headers={"WWW-Authenticate": "Bearer"},
- )
- try:
- payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
- username: str = payload.get("sub")
- if username is None:
- raise credentials_exception
- except JWTError:
- raise credentials_exception
- user = get_user(db, username)
- if user is None:
- raise credentials_exception
- return resp_200(data = user.model_dump())
- def verify_token(token: str):
- try:
- payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
- username: str = payload.get("sub")
- if username is None:
- return False
- return True
- except JWTError:
- return False
- auth_router = router
|