1. 概述
在Web应用程序中,身份验证和授权是常见的功能。保护应用程序中的资源,确保只有认证的用户才能访问它们是很重要的。JSON Web Tokens(JWTs)是一种流行的身份验证和授权机制,其在安全性、可扩展性和互操作性方面都表现良好。
2. 什么是JWT?
JWT全称为JSON Web Token,是一种基于JSON的轻量级身份验证和授权机制。它由三部分组成:
Header(头部):包含指定jwt算法和令牌类型(例如HS256, HS384, HS512等)
Payload(负载):包含要传输的信息(如用户ID、角色、权限等)
Signature(签名):由Header和Payload中的信息加上一个密钥进行签名生成
3. FastAPI与JWT
FastAPI是一个现代、快速(高达每秒4000多个请求)、快速开发的Web框架。它提供了内置支持JWT的包FastAPI-JWT。该包使用PyJWT,除了提供JWT的解析和生成之外,还支持在FastAPI应用程序中提供必要的验证和保护。
4. 安装PyJWT和FastAPI-JWT
我们可以使用pip来安装它们:
pip install PyJWT fastapi_jwt_auth
5. 如何使用FastAPI-JWT
5.1 导入必要的模块
我们需要导入FastAPI,FastAPI-JWT和PyJWT。
from fastapi import FastAPI, Depends
from fastapi_jwt_auth import AuthJWT
import jwt
5.2 在FastAPI应用程序中配置JWT
我们需要指定JWT相关配置,包括秘密密钥,算法等。将此代码放在FastAPI类外的地方。
# Set the jwt secret key
SECRET_KEY = 'secret'
# Set the token expiration time in minutes
ACCESS_TOKEN_EXPIRE_MINUTES = 30
# Set the algorithm to use to sign the jwt payload
ALGORITHM = 'HS256'
5.3 创建FastAPI应用程序
这是一个简单的FastAPI应用程序,用于演示如何使用FastAPI-JWT验证JWT令牌。
app = FastAPI()
# Define some routes that require authentication
@app.get('/protected')
def protected_route(Authorize: AuthJWT = Depends()):
Authorize.jwt_required()
return {'message': 'authenticated user'}
@app.get('/admin')
def admin_route(Authorize: AuthJWT = Depends()):
Authorize.jwt_required()
Authorize.admin_required()
return {'message': 'authenticated admin'}
5.4 生成和验证JWT令牌
为了从FastAPI-JWT库中生成和验证JWT令牌,您需要创建一个叫做“AuthJWT”的对象,并在需要进行身份验证和授权的路由中使用。在下面的示例中,我们指定由FastAPI-JWT库提供的两个装饰器:
@AuthJWT.token_in_header()
:检查HTTP头Authorization中的Bearer令牌
@AuthJWT.jwt_required()
:确保请求者已验证并提供有效凭据
# Create an instance of AuthJWT
auth_jwt = AuthJWT()
# Define a route to generate a jwt token
@app.post('/token')
def login(user: User):
# Get the user from the database
user = get_user_from_db(user.username, user.password)
if user is None:
# Return an error message
return {'error': 'Invalid credentials'}
# Set the user data to be encoded in the jwt payload
access_token = auth_jwt.create_access_token(identity=user.username)
# Return the generated token
return {'access_token': access_token}
# Define a route that requires authentication
@app.get('/protected')
@auth_jwt.token_in_header()
@auth_jwt.jwt_required()
def protected_route():
return {'message': 'authenticated user'}
5.5 自定义验证函数
时常会遇到需要进行更复杂验证的情况,我们可以自定义验证函数来实现。下面是一个自定义验证函数的例子,要求令牌持有者是管理员:
def admin_required(Authorize: AuthJWT = Depends()):
claims = Authorize.get_jwt_claims()
if not claims['is_admin']:
raise HTTPException(
status_code=403,
detail='Admin privilege required'
)
在使用验证函数时,我们可以在需要验证的路由上使用“@auth_jwt.verify_and_update_token”装饰器,然后调用自定义的验证函数。下面是一个验证管理员路由的例子:
@app.get('/admin')
@auth_jwt.token_in_header()
@auth_jwt.verify_and_update_token
def admin_route():
auth_jwt.admin_required()
return {'message': 'authenticated admin'}
总结
使用FastAPI-JWT包,您可以轻松集成JWT身份验证和授权到FastAPI应用程序中。该包提供了一系列API,可以生成和验证JWT令牌,并提供默认和自定义验证功能来保护您的资源。