fastapi 安全性 / APIRouter / BackgroundTasks / 元数据 / 测试调试
文章目录
- 1. 例子
- 2. 获取当前用户
- 3. 使用密码和 Bearer 的简单 OAuth2
- 4. 使用(哈希)密码和 JWT Bearer 令牌的 OAuth2
- 5. 多个应用文件
- 5.1 APIRouter
- 6. BackgroundTasks
- 7. 元数据
- 7.1 标题、描述和版本
- 7.2 openapi_tags 标签元数据
- 7.3 OpenAPI URL
- 7.4 文档 URLs
- 8. 测试
- 9. 调试
learn from https://fastapi.tiangolo.com/zh/tutorial/security/first-steps/
1. 例子
# 安全性 main.py
from fastapi import FastAPI, Depends
from fastapi.security import OAuth2PasswordBearerapp = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# oauth2_scheme(some, parameters) 是课调用的,可以被Depends使用@app.get("/items/")
async def read_items(token: str = Depends(oauth2_scheme)):return {"token": token}
运行 uvicorn main:app --reload
打开 http://127.0.0.1:8000/docs#/default/read_items_items__get
2. 获取当前用户
# 安全性
from fastapi import FastAPI, Depends
from typing import Optional
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModelapp = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# oauth2_scheme(some, parameters) 是课调用的,可以被Depends使用class User(BaseModel):username: stremail: Optional[str] = Nonefull_name: Optional[str] = Nonedisabled: Optional[bool] = Nonedef fake_decode_token(token):return User(username=token+"fakedecoded", email="abc.mail", full_name="michael")async def get_current_user(token: str = Depends(oauth2_scheme)):return fake_decode_token(token)@app.get("/users/me/")
async def read_users_me(current_user: User = Depends(get_current_user)):return current_user
3. 使用密码和 Bearer 的简单 OAuth2
- OAuth2 规定在使用「password 流程」时,客户端/用户必须将
username
和password
字段作为表单数据发送 OAuth2PasswordRequestForm
# 安全性
from fastapi import FastAPI, Depends, HTTPException, status
from typing import Optional
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModelfake_users_db = {"johndoe": {"username": "johndoe","full_name": "John Doe","email": "johndoe@example.com","hashed_password": "fakehashedsecret","disabled": False,},"alice": {"username": "alice","full_name": "Alice Wonderson","email": "alice@example.com","hashed_password": "fakehashedsecret2","disabled": True,},
}def fake_hash_password(password: str):return "fakehashed" + passwordapp = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# oauth2_scheme(some, parameters) 是课调用的,可以被Depends使用class User(BaseModel):username: stremail: Optional[str] = Nonefull_name: Optional[str] = Nonedisabled: Optional[bool] = Noneclass UserInDB(User):hashed_password: strdef get_user(db, username: str):if username in db:user_dict = db[username]return UserInDB(**user_dict) # 过滤,获取hasded_passworddef fake_decode_token(token):return get_user(fake_users_db, token)async def get_current_user(token: str = Depends(oauth2_scheme)):user = fake_decode_token(token)if not user:raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,detail="Invalid authentication credentials",headers={"WWW-Authenticate": "Bearer"},)return userasync def get_current_active_user(current_user: User = Depends(get_current_user)):if current_user.disabled:raise HTTPException(status_code=400, detail="Inactive user")return current_user@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):user_dict = fake_users_db.get(form_data.username)if not user_dict:raise HTTPException(status_code=400, detail="Incorrect username or password")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="Incorrect username or password")return {"access_token": user.username, "token_type": "bearer"}@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):return current_user
4. 使用(哈希)密码和 JWT Bearer 令牌的 OAuth2
- JWT 表示 「JSON Web Tokens」。它是一个将 JSON 对象编码为密集且没有空格的长字符串的标准
- 安装
python-jose
以在 Python 中生成和校验 JWT 令牌
pip install python-jose[cryptography]
PassLib
是一个用于处理哈希密码的很棒的 Python 包, 推荐的算法是 「Bcrypt」
pip install passlib[bcrypt]
参考:https://fastapi.tiangolo.com/zh/tutorial/security/oauth2-jwt/
5. 多个应用文件
__init__.py
可以使得目录下的包可以被其他目录导入,该文件可以为空
5.1 APIRouter
# dependencies.py
# 我们了解到我们将需要一些在应用程序的好几个地方所使用的依赖项。
# 因此,我们将它们放在它们自己的 dependencies 模块from fastapi import Header, HTTPExceptionasync def get_token_header(x_token: str = Header(...)):if x_token != "fake-super-secret-token":raise HTTPException(status_code=400, detail="X-Token header invalid")async def get_query_token(token: str):if token != "jessica":raise HTTPException(status_code=400, detail="No Jessica token provided")
# main.py 你的应用程序中将所有内容联结在一起的主文件
# 你的大部分逻辑现在都存在于其自己的特定模块中
# 因此主文件的内容将非常简单
from fastapi import Depends, FastAPI
from dependencies import get_query_token, get_token_header
from internal import admin
from routers import items, users
# from .routers.items import router # 以下两行名称重叠,注意避免
# from .routers.users import routerapp = FastAPI(dependencies=[Depends(get_query_token)])app.include_router(users.router)
app.include_router(items.router)
# users.router 包含了 app/routers/users.py 文件中的 APIRouter
# items.router 包含了 app/routers/items.py 文件中的 APIRouter
app.include_router(admin.router,prefix="/admin", # 添加路径前缀,而不必修改admin.routertags=["admin"],dependencies=[Depends(get_token_header)],responses={418: {"description": "I'm a teapot"}},# 但这只会影响我们应用中的 APIRouter,# 而不会影响使用admin.router的任何其他代码
)
# app.include_router(),可以将每个 APIRouter 添加到主 FastAPI 应用程序中# 多次使用不同的 prefix 包含同一个路由器
app.include_router(admin.router,prefix="/admin_test", # 添加路径前缀,而不必修改admin.routertags=["admin"],dependencies=[Depends(get_token_header)],responses={418: {"description": "I'm a teapot, diff "}},# 但这只会影响我们应用中的 APIRouter,# 而不会影响使用admin.router的任何其他代码
)# 也可以在另一个 APIRouter 中包含一个 APIRouter
# router.include_router(other_router)@app.get("/")
async def root():return {"message": "Hello Bigger Applications!"}
# internal/admin.py
from fastapi import APIRouterrouter = APIRouter()@router.post("/")
async def update_admin():return {"message": "Admin getting schwifty"}
# routers/items.py
# 此模块中的所有路径操作都有相同的:
# 路径 prefix:/items
# tags:(仅有一个 items 标签)
# 额外的 responses
# dependencies:它们都需要我们创建的 X-Token 依赖项from fastapi import APIRouter, Depends, HTTPException
from dependencies import get_token_header router = APIRouter(prefix="/items", # 前缀不能以 / 作为结尾tags=["items"],dependencies=[Depends(get_token_header)],responses={404: {"description": "Not found"}},# 这些参数将应用于此路由器中包含的所有路径操作
)fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}@router.get("/")
async def read_items():return fake_items_db@router.get("/{item_id}")
async def read_item(item_id: str):if item_id not in fake_items_db:raise HTTPException(status_code=404, detail="Item not found")return {"name": fake_items_db[item_id]["name"], "item_id": item_id}@router.put("/{item_id}",tags=["custom"],responses={403: {"description": "Operation forbidden"}},
) # 这个路径操作将包含标签的组合:["items","custom"]
# 也会有两个响应,一个用于 404,一个用于 403
async def update_item(item_id: str):if item_id != "plumbus":raise HTTPException(status_code=403, detail="You can only update the item: plumbus")return {"item_id": item_id, "name": "The great Plumbus"}
# routers/users.py
# 将与用户相关的路径操作与其他代码分开,以使其井井有条
from fastapi import APIRouter
router = APIRouter()
# 你可以将 APIRouter 视为一个「迷你 FastAPI」类
# 在此示例中,该变量被命名为 router,但你可以根据你的想法自由命名@router.get("/users/", tags=["users"])
async def read_users():return [{"username": "Rick"}, {"username": "Morty"}]@router.get("/users/me", tags=["users"])
async def read_user_me():return {"username": "fakecurrentuser"}@router.get("/users/{username}", tags=["users"])
async def read_user(username: str):return {"username": username}
6. BackgroundTasks
background_tasks.add_task(func, param, keywordparam=value)
- add_task 参数: 函数名, 顺序参数, 关键字参数
from fastapi import BackgroundTasks, FastAPIapp = FastAPI()def write_notification(email: str, message=""):with open("log.txt", mode="w") as email_file:content = f"notification for {email}: {message}"email_file.write(content)
# 任务函数,可以是普通函数 或 async def函数@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks):background_tasks.add_task(write_notification, email, message="hello, sending email to me")# add_task 参数: 函数名, 顺序参数, 关键字参数return {"message": "Notification sent in the background"}
- 依赖注入
from fastapi import BackgroundTasks, FastAPI, Depends
from typing import Optionalapp = FastAPI()def write_log(message: str):with open("log.txt", mode="a") as log:log.write(message)def get_query(background_tasks: BackgroundTasks, q: Optional[str] = None):if q:message = f"found query: {q}\n"background_tasks.add_task(write_log, message)return q@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks, q: str = Depends(get_query)):message = f"message to {email}\n"background_tasks.add_task(write_log, message)return {"message": "Message sent"}
7. 元数据
7.1 标题、描述和版本
from fastapi import BackgroundTasks, FastAPI, Depends
from typing import Optionaldescription = """
goodApp API helps you do awesome stuff.
fastapi 安全性 / APIRouter / BackgroundTasks / 元数据 / 测试调试相关推荐
- 蓝牙认证测试调试记录
这周由于工作原因,接手蓝牙认证测试调试,我们使用的是RDA5876芯片,调试好几次, 都发现DH1.DH3.DH5的数据包都是一样的,怎么调都不行.hciattach初始化参数都已经改了 很多次,还是 ...
- 赛舟-体验版 α测试调试方法
赛舟-体验版 α测试调试方法 1 微信扫描二维码进入小程序 2 点击右上角展开操作面板 3 进入开发调试面板 4 打开调试 5 退出后微信下拉从使用过的小程序再次进入 感性参与本次α测试
- 如何用微信web开发者工具测试调试并打包上传小程序
厦门四六开科技给大家讲讲 如何用微信web开发者工具测试调试并打包上传小程序,其实还是很简单的,这个教程针对小白,大神请直接略过. 一.下载并安装软件(根据自己电脑实际情况选择版本安装) 如何用微信开 ...
- chrome 浏览器 console 加入 jquery 测试调试 一介布衣
chrome 浏览器 console 加入 jquery 测试调试 一介布衣 var jquery = document.createElement('script'); jquery.src = & ...
- java 线程安全性_我如何测试Java类的线程安全性
java 线程安全性 我在最近的一次网络研讨会中谈到了这个问题,现在是时候以书面形式进行解释了. 线程安全是Java等语言/平台中类的重要品质,在Java中我们经常在线程之间共享对象. 缺乏线程安全性 ...
- asp.net web开发步骤_Web 系统安全性测试之会话管理测试
随着因特网的不断发展,人们对网络的使用越来越频繁,通过网络进行购物.支付等其他业务操作.而一个潜在的问题是网络的安全性如何保证,一些黑客利用站点安全性的漏洞来窃取用户的信息,使用户的个人信息泄漏,所以 ...
- 正常web页面登录时效是多少_Web 系统的安全性测试之权限管理测试
随着因特网的不断发展,人们对网络的使用越来越频繁,通过网络进行购物.支付等其他业务操作.而一个潜在的问题是网络的安全性如何保证,一些黑客利用站点安全性的漏洞来窃取用户的信息,使用户的个人信息泄漏,所以 ...
- SUT计算机测试,调试功能测试(徽标) | Microsoft Docs
调试功能测试 (徽标) 03/09/2020 本文内容 此测试测量了测试计算机使用 xHCI 控制器.EHCI 控制器.串行端口.1394控制器或网络适配器支持调试操作的能力. 测试将验证是否至少有一 ...
- 代码测试,调试与优化小结
http://www.cppblog.com/cuijixin/default.html?page=8 代码测试.调试与优化的小结 by falcon<zhangjinw@gmail.com&g ...
最新文章
- 六个深度学习常用损失函数总览:基本形式、原理、特点
- 心得丨机器学习自学指南(覆盖各个阶段的心得体会哦)
- 【 Vivado 】通过IP Integrator进行设计示例
- WWDC2014 IOS8 APP Extensions
- C#基础面试题(学习总结)
- Linux_CentOS-服务器搭建 六
- python upper_Python 3中的模块级string.upper函数在哪里?
- Dubbo-Admin-0.2.0服务管理中心安装
- python学习手册-Python 重点知识整理(基于Python学习手册第四版)
- oracle索引b 树,oracle btree索引概述
- HTML 制作钓鱼网站实现跳转(简篇)
- 555定时器组成的应用之流水灯
- 如何揪出修改浏览器主页的流氓软件1
- mysql中字符串汇总_Mysql中常见字符串处理函数汇总
- matlab读入stl文件,matlab读取stl文件
- HDU 1695(数论,筛选+素因子分解+容斥)
- mysql columns表_mysql8 参考手册-INFORMATION_SCHEMA COLUMNS表
- 行之有效:第一章观后有感
- R语言的帮助使用和图形功能简介
- 无法打开此计算机的组策略,无法运行gpedit.msc(组策略)的解决
热门文章