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

如何正确配置Flask的CORS与Authorization Header?权限路由访问异常

解决Flask CORS带Authorization头路由的跨域问题

我之前也碰到过一模一样的问题——CORS(app)能搞定简单请求,但一涉及带Authorization头的接口就崩,本质是预检请求(OPTIONS)的处理没到位,还有CORS配置没明确允许自定义头。下面给你一步步解决的方案:

1. 先搞懂为什么带Authorization头会报错

浏览器把请求分成「简单请求」和「非简单请求」,带Authorization、Content-Type为application/json这类都属于非简单请求。浏览器会先自动发一个OPTIONS请求去服务器“预检”,确认服务器允许这个请求的来源、头、方法,如果服务器没正确响应OPTIONS请求,就会抛出你看到的那个跨域错误。

2. 调整CORS配置,明确允许所需的头和方法

不要只用CORS(app)这种默认配置,要针对性设置资源路由、允许的来源、头和方法:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)

# 精准配置需要跨域的路由(比如/api下的所有接口)
CORS(app, resources={
    r"/api/*": {
        "origins": "http://localhost:3000",  # 替换成你的React应用域名
        "allow_headers": ["Authorization", "Content-Type"],  # 必须包含Authorization
        "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],  # 要包含OPTIONS方法
        "supports_credentials": True  # 如果你的认证需要带cookie,加上这个
    }
})

⚠️ 注意:origins不要用*,因为当请求带Authorization或凭证时,浏览器不允许用通配符,必须明确写前端的域名。

3. 确保OPTIONS请求不会被认证拦截

如果你用了Flask的认证装饰器(比如@login_required或者自定义的权限校验装饰器),这些装饰器可能会拦截OPTIONS请求——因为OPTIONS请求里不会带Authorization头,直接就返回401了,导致跨域失败。

解决方法是在请求处理前先放行OPTIONS请求:

from flask import request

@app.before_request
def handle_preflight():
    if request.method == 'OPTIONS':
        return '', 200

或者在你的认证装饰器里加判断:

from functools import wraps

def auth_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        # 放行OPTIONS请求
        if request.method == 'OPTIONS':
            return f(*args, **kwargs)
        # 你的认证逻辑...
        token = request.headers.get('Authorization')
        if not token:
            return {"error": "Unauthorized"}, 401
        # 其他校验步骤
        return f(*args, **kwargs)
    return decorated_function

4. 前端fetch请求的配套设置

如果你的请求需要带凭证(比如cookie),要在fetch里加上credentials: 'include';同时确保headers正确设置:

fetch('/api/your-protected-route', {
    method: 'GET',
    headers: {
        'Authorization': `Bearer ${yourToken}`,
        'Content-Type': 'application/json'
    },
    credentials: 'include'  // 和后端的supports_credentials对应
})
.then(response => response.json())
.catch(err => console.error(err));

5. 验证配置是否生效

可以用curl手动发OPTIONS请求测试:

curl -X OPTIONS \
  -H "Origin: http://localhost:3000" \
  -H "Access-Control-Request-Method: GET" \
  -H "Access-Control-Request-Headers: Authorization" \
  http://localhost:5000/api/your-protected-route

看响应头里有没有这些字段:

  • Access-Control-Allow-Origin: http://localhost:3000
  • Access-Control-Allow-Headers: Authorization,Content-Type
  • Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
    如果有,说明CORS配置已经生效了。

按这个流程走下来,带Authorization头的跨域请求应该就能正常工作了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:03:00