Fastapi密码授权相关
主要实现获取token,前端携带token请求
"""
密码授权相关
"""
from fastapi import APIRouter, Depends, Header, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel
from passlib.context import CryptContext
from typing import List, Optional
from datetime import datetime, timedelta
import jwt
auth_app = APIRouter()
# JWT 配置 密钥
SECRET_KEY = "Model"
# 加密算法
ALGORITHM = "HS256"
# token失效时间
ACCESS_TOKEN_EXPIRE_MINUTES = 30
# 密码哈希配置
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# OAuth2 配置
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
hashed_password = pwd_context.hash('123456')
print(hashed_password)
# 定义数据
fake_users_db = {
"haha": {
"username": "haha",
"password": 123456,
"hashed_password": hashed_password,
"disabled": False
},
"james": {
"username": "james",
"password": 123456,
"hashed_password": hashed_password,
"disabled": True
}
}
# 定义数据模型
class Token(BaseModel):
access_token: str
token_type: str
class TokenData(BaseModel):
username: str
class User(BaseModel):
username: str
hashed_password: str
disabled: bool
class UserInDB(User):
hashed_password: str
# 实现数据验证和token生成
def verify_password(plain_password, hashed_password):
print("plain_password:", plain_password)
print("hashed_password", hashed_password)
return pwd_context.verify(plain_password, hashed_password)
def get_user(db, username: str):
if username in db:
user_dict = db[username]
return UserInDB(**user_dict)
def authenticate_user(fake_db, username: str, password: str):
user = get_user(fake_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: 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
async def get_current_user(token: str = Depends(oauth2_scheme)):
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
token_data = TokenData(username=username)
except jwt.PyJWTError:
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:
raise credentials_exception
return user
async def get_current_active_user(current_user: User = Depends(get_current_user)):
if current_user.disabled:
raise HTTPException(status_code=400, detail="Inactive user")
return current_user
@auth_app.post("/token", response_model=Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
user = authenticate_user(fake_users_db, form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user.username}, expires_delta=access_token_expires
)
return {"access_token": access_token, "token_type": "bearer"}
@auth_app.get("/users/me", response_model=User)
async def read_users_me(current_user: User = Depends(get_current_active_user)):
return current_user
测试获取token
输入账号密码拿到token