一文把握异步web框架FastAPI(六)-- 安全(HTTP验证、Bearer Token、Sessi
目录九、安全
1、HTTP 基自己份验证(Basic Authentication)
2、Bearer Token
3、Session 管理
1)简单实现
2)当需要session验证的接口会有多个时,使用中间件来做验证。
3)当有大量接口,此中一些需要登录而另一些不需要时,可以使用FastAPI的依赖注入系统来管理这些接口的访问控制。
4、OAuth2 和 OpenID Connect在fastapi中的应用
1)OAuth2
2)OpenID Connect
5、HTTPS 和 TLS 加密
1)获取 SSL/TLS 证书
自署名证书生成(仅用于开辟测试)
2)设置 FastAPI 使用 HTTPS
3)设置 TLS 加密
4)生产环境摆设发起
6、Rate Limiting (速率限定)
九、安全
1、HTTP 基自己份验证(Basic Authentication)
这是最简单的身份验证形式之一,它要求客户端发送带有用户名和暗码的 HTTP 头部。FastAPI 可以很容易地集成这种身份验证方式。使用 hashlib 对暗码进行哈希处理处罚以提高安全性。
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from hashlib import sha256
app = FastAPI()
security = HTTPBasic()
# 假设我们存储的是密码的哈希值
STORED_USERNAME = "john"
STORED_PASSWORD_HASH = sha256("secret".encode()).hexdigest()
def get_current_username(credentials: HTTPBasicCredentials = Depends(security)):
"""获取当前用户名,并验证提供的凭据是否正确。"""
correct_username = credentials.username == STORED_USERNAME
password_hash = sha256(credentials.password.encode()).hexdigest()
correct_password = password_hash == STORED_PASSWORD_HASH
if not (correct_username and correct_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect user or password",
headers={"WWW-Authenticate": "Basic"},
)
return credentials.username
@app.get("/users/me")
def read_user_me(current_username: str = Depends(get_current_username)):
"""获取当前用户的用户名。"""
return {"username": current_username}
请求:
import requests
from requests.auth import HTTPBasicAuth
# 定义服务器地址
BASE_URL = "http://127.0.0.1:8000"
def test_get_user_me():
# 正确的凭据
correct_credentials = HTTPBasicAuth('john', 'secret')
response = requests.get(f"{BASE_URL}/users/me", auth=correct_credentials)
print("Response with correct credentials:")
print(response.status_code, response.json())
# 错误的凭据
incorrect_credentials = HTTPBasicAuth('john', 'wrongpassword')
response = requests.get(f"{BASE_URL}/users/me", auth=incorrect_credentials)
print("Response with incorrect credentials:")
print(response.status_code, response.text)
if __name__ == "__main__":
test_get_user_me()
https://i-blog.csdnimg.cn/direct/135f9fc3bcd042d3be8181a797cf83f7.png
2、Bearer Token
Bearer token 身份验证是另一种常见的身份验证方法,通常与 OAuth 2.0 团结使用。FastAPI 提供了内置的支持来处理处罚 bearer tokens。
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 假设我们有一个函数来验证 token 是否有效
def fake_decode_token(token):
"""模拟解码令牌的函数,检查令牌是否有效并返回用户信息"""
if token == "validtoken":
return {"username": "john", "scope": "admin"}
else:
return None
async def get_current_user(token: str = Depends(oauth2_scheme)):
"""获取当前用户,如果令牌无效则抛出未授权异常"""
user = fake_decode_token(token)
if user is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token",
headers={"WWW-Authenticate": "Bearer"},
)
return user
@app.get("/users/me")
def read_user_me(current_user=Depends(get_current_user)):
"""读取当前用户的信息"""
return current_user
请求:
import requests
# 定义服务器地址
BASE_URL = "http://127.0.0.1:8000"
def test_get_user_me():
# 正确的令牌
valid_token = "validtoken"
headers = {"Authorization": f"Bearer {valid_token}"}
response = requests.get(f"{BASE_URL}/users/me", headers=headers)
print("Response with valid token:")
print(response.status_code, response.json())
# 错误的令牌
invalid_token = "invalidtoken"
headers = {"Authorization": f"Bearer {invalid_token}"}
response = requests.get(f"{BASE_URL}/users/me", headers=headers)
print("Response with invalid token:")
print(response.status_code, response.text)
if __name__ == "__main__":
test_get_user_me()
https://i-blog.csdnimg.cn/direct/10cb8f8754ec49958da8bf075a48304e.png
3、Session 管理
1)简单实现
from fastapi import FastAPI, Request, HTTPException, status
from fastapi.responses import JSONResponse
from itsdangerous import URLSafeTimedSerializer
import hashlib
import os
def hash_password(password: str) -> str:
# 生成随机盐
salt = os.urandom(16)
# 创建新的哈希对象
hasher = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000)
# 返回盐和哈希值的组合
return salt.hex() + hasher.hex()
def verify_password(stored_password: str, provided_password: str) -> bool:
# 从存储的密码中提取盐
salt = bytes.fromhex(stored_password[:32])
# 提取哈希值
stored_hash = stored_password
# 重新计算哈希值
hasher = hashlib.pbkdf2_hmac('sha256', provided_password.encode('utf-8'), salt, 100000)
# 比较哈希值
return hasher.hex() == stored_hash
app = FastAPI()
serializer = URLSafeTimedSerializer("SECRET_KEY")
# 假设的用户数据库
fake_users_db = {
"alice": {
"username": "alice",
"hashed_password": hash_password("secret_password")
}
}
def authenticate_user(fake_db, username: str, password: str):
user = fake_db.get(username)
if not user or not verify_password(user["hashed_password"], password):
return False
return user
@app.post("/login")
async def login(request: Request):
data = await request.json()
username = data.get('username')
password = data.get('password')
user = authenticate_user(fake_users_db, username, password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
session_token = serializer.dumps(username)
response = JSONResponse({"message": "Login successful"})
response.set_cookie(key="session_token", value=sessi
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]