You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask集成Auth0疑问:如何在请求头中放置授权令牌?

如何在请求头中携带Auth0授权令牌?

我正在项目中集成Auth0,但不清楚怎么把授权令牌(authorization token)放到请求头里。我已经跟着Auth0官方文档操作了,但还是有困惑,以下是我目前的代码:

auth.py

ENV_FILE = find_dotenv()
if ENV_FILE:
    load_dotenv(ENV_FILE)

oauth = OAuth(app)

oauth.register(
    "auth0",
    client_id=env.get("AUTH0_CLIENT_ID"),
    client_secret=env.get("AUTH0_CLIENT_SECRET"),
    client_kwargs={
        "scope": "openid profile email",
    },
    server_metadata_url=f'https://{env.get("AUTH0_DOMAIN")}/.well-known/openid-configuration'
)

# 登录验证装饰器
def login_required(func):
    @wraps(func)
    def decorated_function(*args, **kwargs):
        if not session.get("user"):
            return redirect(url_for("login"))
        return func(*args, **kwargs)
    return decorated_function

require_auth = ResourceProtector()
validator = Auth0JWTBearerTokenValidator(
    "dev-dzlqn0602x1umzhg.us.auth0.com",
    "https://localhost:5000"
)
require_auth.register_token_validator(validator)

@app.route("/login")
def login():
    return oauth.auth0.authorize_redirect(
        redirect_uri=url_for("callback", _external=True)
    )

@app.route("/callback", methods=["GET", "POST"])
def callback():
    token = oauth.auth0.authorize_access_token()
    session["user"] = token
    return redirect("/")

@app.route("/public")
def public():
    """无需访问令牌"""
    response = (
        "这是公开接口!无需认证即可访问。"
    )
    return jsonify(message=response)

@app.route("/private")
@require_auth(None)
def private():
    """需要有效访问令牌"""
    response = (
        "这是私有接口!需要认证才能访问。"
    )
    return jsonify(message=response)


@app.route("/private-scoped")
@require_auth("read:all")
def private_scoped():
    """需要有效访问令牌及指定权限"""
    response = (
        "这是带权限的私有接口!需要认证且拥有read:all权限才能访问。"
    )
    return jsonify(message=response)

@app.route("/logout")
def logout():
    session.clear()
    return redirect(
        "https://" + env.get("AUTH0_DOMAIN")
        + "/v2/logout?"
        + urlencode(
            {
                "returnTo": url_for("home", _external=True),
                "client_id": env.get("AUTH0_CLIENT_ID"),
            },
            quote_via=quote_plus,
        )
    )

解决方法

1. 后端内部调用时添加令牌

你的代码已经在callback路由将Auth0返回的令牌存入session["user"],其中包含access_token字段。如果后端需要调用其他受保护的API,直接从session取出令牌并构造请求头:

import requests

@app.route("/call-external-protected-api")
@login_required
def call_external_api():
    access_token = session["user"]["access_token"]
    headers = {
        "Authorization": f"Bearer {access_token}"
    }
    res = requests.get("https://your-target-protected-api", headers=headers)
    return jsonify(result=res.json())

2. 前端请求私有接口时携带令牌

如果是前端页面调用你的/private这类接口,需要在请求头里添加Authorization: Bearer <access_token>:

以JavaScript的fetch为例:

fetch("/private", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${localStorage.getItem("auth_access_token")}`
  }
})
.then(res => res.json())
.then(data => console.log(data));

要实现这个,你需要在callback路由把令牌传递给前端,比如渲染模板时注入:

@app.route("/callback", methods=["GET", "POST"])
def callback():
    token = oauth.auth0.authorize_access_token()
    session["user"] = token
    # 渲染首页时将access_token传给模板
    return render_template("home.html", access_token=token["access_token"])

然后在模板里把令牌存入localStorage:

<script>
  localStorage.setItem("auth_access_token", "{{ access_token }}");
</script>

3. 令牌验证的关键配置修正

你的Auth0JWTBearerTokenValidator第二个参数是API的Audience(受众),必须和Auth0控制台中你创建的API的Audience完全一致,不是你的应用地址。如果你的API Audience是https://my-api.example.com,修正如下:

validator = Auth0JWTBearerTokenValidator(
    "dev-dzlqn0602x1umzhg.us.auth0.com",
    "https://my-api.example.com"  # 替换为Auth0中设置的API Audience
)

内容的提问来源于stack exchange,提问作者Nicolas Pullen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:02:18