以下是一种不需要数据库访问的JWT身份验证的解决方法,包含代码示例。
import jwt
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from passlib.context import CryptContext
# 配置JWT密钥
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
# 创建密码上下文对象
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# 创建OAuth2密码授权验证对象
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 模拟从数据库获取用户信息
def get_user(username: str):
# 在这个例子中,我们假设有一个预定义的用户列表
users = [
{"username": "user1", "password": "$2b$12$wBmA1d9Z5H3k56WxR0Ys6e7u6jyQQR9z4XJZP9gB1rG43bntbEJ7e"},
{"username": "user2", "password": "$2b$12$wBmA1d9Z5H3k56WxR0Ys6e7u6jyQQR9z4XJZP9gB1rG43bntbEJ7e"},
]
for user in users:
if user["username"] == username:
return user
return None
# 验证用户密码
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
# 创建JWT令牌
def create_access_token(data: dict):
encoded_jwt = jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
# 解析JWT令牌
def decode_token(token: str):
try:
decoded_token = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return decoded_token
except jwt.DecodeError:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Expired token")
# 创建获取当前用户的依赖项
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 = decode_token(token)
username: str = payload.get("sub")
if username is None:
raise credentials_exception
except jwt.PyJWTError:
raise credentials_exception
user = get_user(username)
if user is None:
raise credentials_exception
return user
# 示例路由,需要身份验证
@app.get("/protected_route")
def protected_route(current_user: dict = Depends(get_current_user)):
return {"message": "Authorized access", "user": current_user}
在上面的代码示例中,我们使用了jwt
库来创建和解析JWT令牌。fastapi
库提供了OAuth2PasswordBearer
类,用于处理密码授权验证。我们使用passlib
库来处理密码散列。
用户信息是在get_user
函数中模拟从数据库获取的。在实际应用中,您可以根据自己的需求来实现用户信息的获取方式。
create_access_token
函数用于创建JWT令牌,decode_token
函数用于解析JWT令牌。get_current_user
函数是一个依赖项,用于从令牌中获取当前用户的信息。
protected_route
是一个示例路由,它需要进行身份验证。如果请求中提供的令牌有效并且用户存在,则返回授权访问的消息和当前用户信息。如果令牌无效或用户不存在,则返回相应的错误信息。
请注意,上述示例代码中的密码是散列的,并且使用了bcrypt算法进行散列。在实际应用中,您可能需要根据自己的需求来选择合适的散列算法,并确保密码的安全性。