首页 > 解决方案 > FastAPI 和 SqlAlcham:使用“代表”访问令牌查询 Azure SQL 数据库

问题描述

问题

假设用户使用来自 Azure 的 JWT 令牌向我的 API (Python FastAPI)发出请求,并且我能够使用以下代码代表用户获取数据库的新访问令牌:

import msal
from flask import request

CLIENT_ID="XXX"
CLIENT_SECRET="XXX"
TENANT_ID="XXX"

auth = msal.ConfidentialClientApplication(
    client_id=CLIENT_ID
    client_credential=CLIENT_SECRET,
    authority=f"https://login.microsoftonline.com/{TENANT_ID}")

request.headers.get('Authorization')
parts = auth.split(' ')
access_token = parts[1]
token = auth.acquire_token_on_behalf_of(
    user_assertion=access_token,
    scopes='https://database.windows.net/.default')

现在我想使用这个令牌查询数据库。到目前为止,我已经为每个传入请求创建了一个 SqlAlchemy 引擎,而不是查询数据库:

from sqlalchemy.engine import create_engine
from sqlalchemy.orm import sessionmaker
import struct
import urllib.parse

host='XXX'
databse='XXX'
port='1433'
driver='{ODBC Driver 17 for SQL Server}'

token_bytes = bytes(token.token, "UTF-8")
exp_token = b''
for i in token_bytes:
    exp_token += bytes({i})
    exp_token += bytes(1)
token_struct = struct.pack("=i", len(exp_token)) + exp_token
attrs_before = {1256: token_struct}
cnxstr = f"Driver={driver};SERVER={host},{port};DATABASE={databse}"
params = urllib.parse.quote(cnxstr)
engine = create_engine(
    f"mssql+pyodbc:///?odbc_connect={params}",
    connect_args={'attrs_before': attrs_before})
Session = sessionmaker(bind=engine)
session = Session()
session.execute('SELECT ...')

使用 SqlAlchemy,我只能将“代表”令牌attrs_before传递给引擎 - 我是否需要为对我的 API 的每个请求创建一个引擎?或者有更清洁的方法吗?例如,通过每个请求只创建一个会话并将令牌放入其中?

出现以下问题:

标签: pythonsqlalchemyjwtazure-sql-databasefastapi

解决方案


推荐阅读