如何使用客户端 ID 和密码将 OAuth 实施到 FastAPI
How to implement OAuth to FastAPI with client ID & Secret
我已经关注了关于 Oauth2 的文档,但它没有描述添加客户端 ID 和密码的过程
https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/
以及它的作用
class UserInDB(User):
hashed_password: str
来自原始示例
在文档中,它使用 OAuth2PasswordRequestForm
来验证用户,这个 class 基本上有 6 个不同的字段,
grant_type: str = Form(None, regex="password"),
username: str = Form(...),
password: str = Form(...),
scope: str = Form(""),
client_id: Optional[str] = Form(None),
client_secret: Optional[str] = Form(None),
所以你可以添加 client_id
和 client_secret
,如果你有兴趣 Repository 这里。
但我通常更喜欢authlib
,这样可以节省很多时间,而且更容易。这是一个完整的示例,说明如何使用 authlib
创建 OAuth
首先创建一个 OAuth 客户端
from authlib.integrations.starlette_client import OAuth
from starlette.config import Config
config = Config('.env') # read config from .env file
oauth = OAuth(config)
oauth.register(
name='google',
server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
client_kwargs={
'scope': 'openid email profile'
}
)
我们不需要在这里添加client_id和client_secret,因为它们在.env文件中。您不应该在代码中对它们进行硬编码,实际上 products.Google 有一个 OpenID 发现端点,我们可以将此 URL 用于 server_metadata_url
。 Authlib 将自动获取此 server_metadata_url
来为您配置 OAuth 客户端。
现在我们将创建一个 FastAPI 应用程序来定义登录路由。
from fastapi import FastAPI, Request
from starlette.middleware.sessions import SessionMiddleware
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="secret-string")
我们需要这个 SessionMiddleware,因为 Authlib 将使用 request.session
来存储临时代码和状态。下面的代码是 /login
端点,会将您重定向到 Google 帐户网站。
@app.route('/login')
async def login(request: Request):
redirect_uri = request.url_for('auth')
return await oauth.google.authorize_redirect(request, redirect_uri
当您从 Google 网站授予访问权限时,Google 将重定向回您给定的 redirect_uri
,即 request.url_for('auth')
:
@app.route('/auth')
async def auth(request: Request):
token = await oauth.google.authorize_access_token(request)
user = await oauth.google.parse_id_token(request, token)
return user
以上代码会得到一个包含access_token和id_token的token。一个id_token包含用户信息,我们只需要解析它就可以得到登录用户的信息。
来源:Authlib-FastAPI-Google-Login
此外,如果您仍想使用 Pure FastAPI,请检查此 link FastAPI OAuth2PasswordRequestForm
我已经关注了关于 Oauth2 的文档,但它没有描述添加客户端 ID 和密码的过程
https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/
以及它的作用
class UserInDB(User):
hashed_password: str
来自原始示例
在文档中,它使用 OAuth2PasswordRequestForm
来验证用户,这个 class 基本上有 6 个不同的字段,
grant_type: str = Form(None, regex="password"),
username: str = Form(...),
password: str = Form(...),
scope: str = Form(""),
client_id: Optional[str] = Form(None),
client_secret: Optional[str] = Form(None),
所以你可以添加 client_id
和 client_secret
,如果你有兴趣 Repository 这里。
但我通常更喜欢authlib
,这样可以节省很多时间,而且更容易。这是一个完整的示例,说明如何使用 authlib
首先创建一个 OAuth 客户端
from authlib.integrations.starlette_client import OAuth
from starlette.config import Config
config = Config('.env') # read config from .env file
oauth = OAuth(config)
oauth.register(
name='google',
server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
client_kwargs={
'scope': 'openid email profile'
}
)
我们不需要在这里添加client_id和client_secret,因为它们在.env文件中。您不应该在代码中对它们进行硬编码,实际上 products.Google 有一个 OpenID 发现端点,我们可以将此 URL 用于 server_metadata_url
。 Authlib 将自动获取此 server_metadata_url
来为您配置 OAuth 客户端。
现在我们将创建一个 FastAPI 应用程序来定义登录路由。
from fastapi import FastAPI, Request
from starlette.middleware.sessions import SessionMiddleware
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="secret-string")
我们需要这个 SessionMiddleware,因为 Authlib 将使用 request.session
来存储临时代码和状态。下面的代码是 /login
端点,会将您重定向到 Google 帐户网站。
@app.route('/login')
async def login(request: Request):
redirect_uri = request.url_for('auth')
return await oauth.google.authorize_redirect(request, redirect_uri
当您从 Google 网站授予访问权限时,Google 将重定向回您给定的 redirect_uri
,即 request.url_for('auth')
:
@app.route('/auth')
async def auth(request: Request):
token = await oauth.google.authorize_access_token(request)
user = await oauth.google.parse_id_token(request, token)
return user
以上代码会得到一个包含access_token和id_token的token。一个id_token包含用户信息,我们只需要解析它就可以得到登录用户的信息。
来源:Authlib-FastAPI-Google-Login
此外,如果您仍想使用 Pure FastAPI,请检查此 link FastAPI OAuth2PasswordRequestForm