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

Next.js中使用授权码模式获取认证令牌的CORS错误解决

问题分析与解决方案

问题根源

  1. CORS限制:DocuSign的/oauth/token接口未配置允许http://localhost:3000的跨域请求,浏览器会拦截前端发起的直接请求。
  2. 安全风险:你将client_secret通过NEXT_PUBLIC_前缀的环境变量暴露在前端代码中,这严重违反OAuth 2.0安全规范——client_secret必须仅在后端环境中保密存储。

推荐解决方案:通过Next.js API路由代理请求

利用Next.js的后端API路由作为中间层,由后端发起DocuSign的token请求(后端请求不受浏览器CORS限制,同时能保护敏感凭证)。

步骤1:创建后端API路由

在项目中新建pages/api/docusign-token.js(App Router对应路径为app/api/docusign-token/route.js),写入以下代码:

// pages/api/docusign-token.js
export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  const { code } = req.body;
  if (!code) {
    return res.status(400).json({ error: 'Authorization code is required' });
  }

  try {
    const tokenUrl = "https://account-d.docusign.com/oauth/token";
    // 注意:不要用NEXT_PUBLIC_前缀,确保凭证仅在后端加载
    const integrationKey = process.env.DOCUSIGN_INTEGRATION_KEY;
    const clientSecret = process.env.DOCUSIGN_CLIENT_SECRET;

    const encodedSecret = btoa(`${integrationKey}:${clientSecret}`);
    const headers = {
      "Authorization": `Basic ${encodedSecret}`,
      "Content-Type": "application/x-www-form-urlencoded",
    };
    const body = new URLSearchParams({
      grant_type: "authorization_code",
      code: code,
    });

    const response = await fetch(tokenUrl, {
      method: "POST",
      headers: headers,
      body: body,
    });

    if (!response.ok) {
      const errorData = await response.json().catch(() => null);
      throw new Error(`Failed to fetch token: ${response.status} ${errorData?.error || response.statusText}`);
    }

    const data = await response.json();
    res.status(200).json(data);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
}

步骤2:修改前端请求代码

将原有的前端直接调用DocuSign接口的代码,改为调用自己的API路由:

useEffect(() => {
  const getAuthToken = async () => {
    if (!oAuthCode) return;

    try {
      const response = await fetch('/api/docusign-token', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ code: oAuthCode }),
      });

      if (!response.ok) {
        throw new Error(`Failed to get access token: ${response.status} ${response.statusText}`);
      }
      const data = await response.json();
      setAuthToken(data.access_token);
    } catch (error) {
      console.error(error);
    }
  };
  getAuthToken();
}, [oAuthCode]);

本地临时测试方案(仅用于开发,禁止生产使用)

如果只是本地开发临时验证流程,可以使用CORS代理工具绕过限制,但绝对不能用于生产环境(会暴露敏感凭证):

// 仅本地测试用,生产环境删除
const tokenUrl = "https://cors-anywhere.herokuapp.com/https://account-d.docusign.com/oauth/token";

核心注意事项

  • 必须移除环境变量的NEXT_PUBLIC_前缀,确保DOCUSIGN_CLIENT_SECRET仅在后端环境中加载,不暴露给前端用户。
  • DocuSign的OAuth 2.0规范明确要求:授权码模式的token请求必须由后端发起,前端直接调用不符合安全要求,这也是该接口不允许跨域的根本原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:57:21