React前端调用MasterCard Finicity API遇CORS错误求助
解决Finicity API的CORS拦截问题
核心原因
你当前的问题本质是浏览器同源策略限制:Finicity的API服务器未配置允许你的前端域名(http://localhost:3000)跨域访问,因此浏览器会拦截响应。另外你在前端请求中添加的Access-Control-Allow-Origin、Access-Control-Allow-Methods完全无效——这些是服务器返回给浏览器的响应头,并非前端请求需要携带的头。
no-cors模式虽能绕过拦截,但浏览器会完全屏蔽响应内容,自然拿不到令牌;ngrok/HTTPS仅解决了协议或公网域名问题,只要Finicity未将你的域名加入白名单,CORS错误就会持续存在。
正确解决方案:用Django后端做代理
你已有Django后端且密钥存储在.env中,最稳妥的方式是让Django作为中间层:前端调用自身的Django接口,由Django去请求Finicity的API。后端之间的HTTP请求不受浏览器CORS限制,可完美绕开该问题。
步骤1:在Django中新增代理视图
先安装requests库用于发送HTTP请求:
pip install requests
在Django的app中新增视图函数:
# views.py import os import requests from django.http import JsonResponse from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated @api_view(['POST']) @permission_classes([IsAuthenticated]) def finicity_get_token(request): # 从.env读取Finicity敏感密钥(避免前端传递泄露) finicity_app_key = os.environ.get('FINICITY_APP_KEY') partner_id = os.environ.get('FINICITY_PARTNER_ID') partner_secret = os.environ.get('FINICITY_PARTNER_SECRET') # 请求Finicity认证接口 url = "https://api.finicity.com/aggregation/v2/partners/authentication" headers = { 'Content-Type': 'application/json', 'Finicity-App-Key': finicity_app_key, 'Accept': 'application/json' } payload = { "partnerId": partner_id, "partnerSecret": partner_secret } try: response = requests.post(url, json=payload, headers=headers) response.raise_for_status() # 触发HTTP错误异常 return JsonResponse(response.json(), status=response.status_code) except requests.exceptions.RequestException as e: error_status = response.status_code if 'response' in locals() else 500 return JsonResponse({"error": str(e)}, status=error_status)
在urls.py中添加对应路由:
from django.urls import path from . import views urlpatterns = [ # 其他已有路由... path('api/finicity/token/', views.finicity_get_token, name='finicity-token'), ]
步骤2:修改前端代码,调用Django代理接口
将原getAccessToken函数改为调用自身的Django接口:
const getAccessToken = async() => { const token = authTokens.access; try { const response = await fetch('http://127.0.0.1:8000/api/finicity/token/', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', }, }); if (response.ok) { const secondData = await response.json(); console.log(secondData); } else { alert('获取Finicity令牌失败'); } } catch (error) { console.error('令牌请求错误:', error); alert('令牌请求出现异常'); } }
额外注意事项
- 所有Finicity敏感密钥(app_key、partner_id、partner_secret)必须存在Django的.env文件中,绝对不能通过前端传递,防止泄露。
- 确保Django配置允许前端域名跨域访问(可使用
django-cors-headers库):# settings.py INSTALLED_APPS = [ # ... 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... ] CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", # 若使用ngrok,添加你的ngrok域名 ]
内容的提问来源于stack exchange,提问作者Tolu
相关产品推荐
相关产品推荐

