FastAPI 學習之路(二十八)使用密碼和 Bearer 的簡單 OAuth2


   OAuth2 規定在使用(我們打算用的)「password 流程」時,客戶端/用戶必須將 username 和 password 字段作為表單數據發送。我們看下在我們應該去如何實現呢。

        我們寫一個登錄接口,默認返回token和token_type

from fastapi import FastAPI, Depends,status,HTTPException
from pydantic import BaseModel
from typing import Optional
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
fake_users = {
    "leizi": {
        "username": "leizi",
        "full_name": "leizishuoceshikaifa",
        "email": "leizi@leizi.com",
        "hashed_password": "leizi",
        "disabled": False
    }
}
app = FastAPI()


def fake_hash_password(password: str):
    return password


class User(BaseModel):
    username: str
    email: Optional[str] = None
    full_name: Optional[str] = None
    disabled: Optional[bool] = None
class UserInDB(User):
    hashed_password: str

def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)
def fake_decode_token(token):
    user = get_user(fake_users, token)
    return user


def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    print(user)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user
@app.post("/login")
def login(form_data: OAuth2PasswordRequestForm = Depends()):
#校驗密碼¶
# 目前我們已經從數據庫中獲取了用戶數據,但尚未校驗密碼。

# 讓我們首先將這些數據放入 Pydantic UserInDB 模型中。
# 永遠不要保存明文密碼,因此,我們將使用(偽)哈希密碼系統。

# 如果密碼不匹配,我們將返回同一個錯誤。


    user_dict = fake_users.get(form_data.username)
    print(user_dict)
    if not user_dict:
        raise HTTPException(status_code=400, detail="用戶名錯誤")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="密碼錯誤 ")

    return {"access_token": user.username, "token_type": "bearer"}

@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
    print(current_user)
    return current_user

  我們去測試下登錄

 

     那么我們在測試下帶認證的

 

 沒有帶認證,那么我們帶下認證看下是否正確

 

 

  我們看下接口返回正確。

代碼中的:

        UserInDB(**user_dict) 表示:

        直接將 user_dict 的鍵和值作為關鍵字參數傳遞,等同於:

UserInDB(
    username = user_dict["username"],
    email = user_dict["email"],
    full_name = user_dict["full_name"],
    disabled = user_dict["disabled"],
    hashed_password = user_dict["hashed_password"],
)

        加入我們的狀態現在改成了True

fake_users = {
    "leizi": {
        "username": "leizi",
        "full_name": "leizishuoceshikaifa",
        "email": "leizi@leizi.com",
        "hashed_password": "leizi",
        "disabled": True
    }
}

我們不想讓disabled為True的時候不能獲取。我們看下如何實現的

def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="已經刪除")
    return current_user
@app.get("/users/me")
def read_users_me(current_user: User = Depends(get_current_active_user)):
   
    return current_user

 其實很簡單,我們就是在獲取的依賴增加了另一個是否是active的判斷的依賴。

文章首發在公眾號,歡迎關注。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM