文章目录
本文阐述了如何基于FastAPI
框架实现 OAuth2
用户认证,其中使用哈希算法对密码进行了加密,使用 JWT
持有令牌。
附带完整的代码,避免大家再次踩坑。
关于 OAuth2
OAuth
是一个关于授权(authorization
)的开放网络标准,在全世界得到广泛应用。比如:微信登录、Facebook,Google,Twitter,GitHub等。
OAuth2
规范要求使用密码流时,客户端或用户必须以表单数据形式发送 username
和 password
字段。这两个字段必须命名为 username
和 password
,不能使用 user-name
或 email
等其它名称。
该规范要求必须以表单数据形式发送 username 和 password,因此,不能使用 JSON 对象。
当然,前端仍可以显示终端用户所需的名称,数据库模型也可以使用自己定义的名称。
关于OAuth的更多知识,您可以参考:理解OAuth2.0
关于 JWT
JWT
即JSON 网络令牌(JSON Web Tokens
)是目前最流行的跨域认证解决方案。它在服务端将用户信息进行签名(如果有保密信息也可以加密后再签名),这样可以防止它被篡改。
每次客户端提交请求时,都附带 JWT
内容,这样服务端可以直接读取用户信息,而不用必须从服务器端的会话中获取。
关于JWT的更多知识,可以参考:JSON Web Token 入门教程
安装依赖
# 安装 PyJWT,在 Python 中生成和校验 JWT 令牌
pip install pyjwt
# Passlib 是处理密码哈希的 Python 包,支持很多安全哈希算法及配套工具。
# 本教程推荐的算法是 Bcrypt。
pip install passlib[bcrypt]
准备用户数据库
这里准备了用户数据和处理用户对象的简单方法,没有真正链接数据库。
from fastapi import Depends, FastAPI,HTTPException,status
from fastapi.security import OAuth2PasswordBearer,OAuth2PasswordRequestForm
from pydantic import BaseModel
from passlib.context import CryptContext
from datetime import datetime, timedelta, timezone
import jwt
from jwt.exceptions import InvalidTokenError
from typing import Union
from typing import Annotated
# 模仿用户数据库
fake_users_db = {
"liu": {
"username": "liu",
"full_name": "Jack Liu",
"email": "liupras@gmail.com",
"hashed_password": "$2b$12$XMT2KGR.3pBUszKSl91I6uJDWVZIncZMyqgXzH1KnWqZcPZ/k5pLu", #12345678
"disabled": False,
},
"wang": {
"username": "wang",
"full_name": "Errin Wang",
"email": "56008507@qq.com",
"hashed_password": "$2b$12$WjyqXlyP/TCyysi0HwLWGenjP668dBswX39aKJzByZTlTDZ9kD.5e", #23456789
"disabled": True,
},
}
# Token实体
class Token(BaseModel):
access_token: str
token_type: str
class TokenData(BaseModel):
username: str | None