在Web應用開發中,鑒權系統是必不可少的一個環節。FastAPIJWT是使用JSON Web Token(以下簡稱JWT)在FastAPI中構建鑒權系統的一種簡單、快速但功能強大的方法。JWT是一種開放標準(RFC 7519),用於在網路應用之間傳遞聲明。JWT中的信息使用JSON對象進行編碼,以數字簽名方式進行驗證。
一、在FastAPI中使用FastAPIJWT
在開始使用FastAPIJWT之前,需要使用pip安裝FastAPI和FastAPIJWT庫:
pip install fastapi
pip install fastapi-jwt-auth
接下來,我們需要在FastAPI應用程序中添加FastAPIJWT的配置項和路由以啟用鑒權系統。
在應用程序的主文件中,導入FastAPI、FastAPIJWT庫並創建應用程序實例:
from fastapi import FastAPI
from fastapi_jwt_auth import AuthJWT
app = FastAPI()
接下來,我們需要配置FastAPIJWT並在應用程序中註冊路由以處理jwt相關的請求。這裡我們使用AuthJWT裝飾器,該裝飾器接受應用程序實例作為參數。配置中我們需要設置SECRET_KEY、ACCESS_TOKEN_EXPIRE_MINUTES和ALGORITHM參數,在路由中我們可以通過AuthJWT.current_user()方法獲取當前用戶的信息:
# 必須設置的Secret Key以進行JWT加密和解密
app.config["SECRET_KEY"] = "your-secret-key"
# JWT過期時間(分鐘)
app.config["ACCESS_TOKEN_EXPIRE_MINUTES"] = 30
# JWT演算法
app.config["ALGORITHM"] = "HS256"
# JWT鑒權路由
@app.post("/login")
def login(auth: AuthJWT = Depends()):
# 獲取用戶名和密碼
username = form_data.username
password = form_data.password
# 驗證用戶
is_authenticated = verify_user(username, password)
if is_authenticated:
# 創建JWT令牌
access_token = auth.create_access_token(subject=username)
return {"access_token": access_token}
else:
raise HTTPException(status_code=400, detail="Incorrect username or password")
@app.get("/protected")
def protected_route(user: User = Depends(get_current_user)):
return {"message": "Hello, {0}!".format(user.username)}
在上面的示例中,我們使用了兩個路由:/login和/protected。在/login路由中,我們獲取用戶的用戶名和密碼,並驗證用戶身份。如果用戶身份驗證成功,則調用AuthJWT.create_access_token()方法生成JWT令牌並返回給客戶端。在/protected路由中,我們使用@Depends裝飾器中的get_current_user方法來保護該路由。
二、使用FastAPIJWT保護路由
在上一節中,我們已經使用FastAPIJWT創建了鑒權系統。在本節中,我們將使用FastAPIJWT來保護我們的路由,僅允許經過身份驗證的用戶訪問。
首先,我們需要創建一個獲取當前用戶的函數(也稱為依賴項),該函數將在路由中使用。
from fastapi_jwt_auth import AuthJWTfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentialsfrom fastapi import Dependsjwt_scheme = HTTPBearer()# 獲取當前用戶的函數def get_current_user(auth: HTTPAuthorizationCredentials = Depends(jwt_scheme), jwt: AuthJWT = Depends()): try: # 調用AuthJWT.verify_token()方法驗證token並返回用戶信息 jwt.verify_token(auth.credentials) current_user = jwt.get_jwt_subject() except: # 驗證失敗時拋出HTTPException raise HTTPException(status_code=401, detail="Invalid token") return {"username": current_user}
在上述get_current_user方法中,我們使用@Depends裝飾器指定了兩個依賴項:auth和jwt。其中auth參數的值為FastAPI的HTTPBearer OAuth類型,用於獲取HTTP頭部中的JWT密碼。jwt參數的值為AuthJWT實例,用於驗證JWT密碼和獲取JWT主題(即用戶標識符)。如果驗證成功,則返回包含用戶名的JSON對象。如果驗證失敗,則返回401 UnauthorizedHTTPException。接下來,我們可以在要保護的路由中使用該get_current_user方法。
# 保護路由
@app.get("/protected")
def protected_route(user: User = Depends(get_current_user)):
return {"message": "Hello, {0}!".format(user.username)}
在上述示例中,我們使用fastapi的@Depends裝飾器來指定get_current_user方法作為get_protected_route路由的依賴項。如果用戶通過身份驗證,則返回包含用戶信息的JSON對象。如果用戶未通過身份驗證,則返回401 Unauthorized HTTPException。
三、使用Refresh Token實現JWT自動續期
JWT的過期時間是有限的。但是,如果用戶一直在使用應用程序,他們可能希望在該時間段內自動續訂他們的JWT。為了實現這一點,FastAPIJWT提供了一個自動續訂機制,該機制使用Refresh Token。
在FastAPIJWT中,Refresh Token是一種與訪問令牌(access token)相關的短暫的JWT。Refresh Token創建後的短暫有效期內可以用來獲取新的訪問令牌,從而允許用戶無縫延長訪問令牌的有效期。
要使用Refresh Token,請指定一個可選的REFRESH_TOKEN_EXPIRE_MINUTES選項,該選項指定Refresh Token的過期時間。以下是實現JWT自動續期的示例:
# JWT自動續訂路由
@app.post("/refresh")
def refresh_token(authorize: AuthJWT = Depends()):
# 驗證Refresh Token
authorize.jwt_refresh_token_required()
# 創建新的AccessToken
current_user = authorize.get_jwt_subject()
new_access_token = authorize.create_access_token(subject=current_user)
# 返回新的AccessToken
return {"access_token": new_access_token, "refresh_token": authorize.create_refresh_token(subject=current_user)}
在上述示例中,我們使用AuthJWT裝飾器和create_refresh_token()方法創建了Refresh Token。如果Refresh Token存在且有效,則可以調用create_access_token()方法創建新的Access Token。
此時,我們需要相應地更新前一節中的login()路由和get_current_user()函數。
# Login路由
@app.post("/login")
def login(form_data: LoginForm, authorize: AuthJWT = Depends()):
# 獲取用戶名和密碼
username = form_data.username
password = form_data.password
# 驗證用戶
is_authenticated = verify_user(username, password)
if is_authenticated:
# 創建JWT令牌和Refresh Token
access_token = authorize.create_access_token(subject=username)
refresh_token = authorize.create_refresh_token(subject=username)
return {"access_token": access_token, "refresh_token": refresh_token}
else:
raise HTTPException(status_code=400, detail="Incorrect username or password")
# 獲取當前用戶的函數
def get_current_user(authorize: AuthJWT = Depends()):
try:
# 調用AuthJWT.refresh_jwt_token()方法來刷新Token
authorize.jwt_refresh_token_required()
authorize.refresh_jwt_token()
current_user = authorize.get_jwt_subject()
except:
# 驗證失敗時拋出HTTPException
raise HTTPException(status_code=401, detail="Invalid token")
return {"username": current_user}
在上述示例中,我們使用AuthJWT.refresh_jwt_token()方法來刷新JWT。如果Refresh Token有效,則會自動創建新的Access Token並返回給客戶端。
四、結語
到目前為止,我們已經使用FastAPIJWT構建了一個功能齊全的Web應用程序鑒權系統,實現了訪問控制和自動續訂功能。FastAPIJWT是使用FastAPI創建鑒權系統的最佳選擇之一,因為它結合了FastAPI的速度和易用性,以及JWT提供的強大的安全保障。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/253894.html