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

Firebase Functions中Instagram OAuth2认证提示client_id缺失问题

解决Instagram OAuth2认证中oauth2.getToken报"Missing required field client_id"错误

问题描述

我正在为Firebase应用搭建Instagram认证流程,后端采用Firebase Functions(基于Express和Node.js),参考官方教程及示例代码开发。目前流程第一步通过window.location()跳转到authToInstagram函数后,能成功重定向至Instagram完成登录授权,但在回调函数instagramCallback中调用oauth2.getToken时,持续报错ERROR : Missing required field client_id。

已确认client_id和secret配置正确,且能在URL参数中看到client_id,尝试过fetch传参、res.json/res.send、添加bodyParser.json()等方法均无效,无法确定该在何处正确传入client_id。

相关代码

// authToInstagram函数
export const authToInstagram = functions.https.onRequest((req, res)=>{
  cookieParser()(req, res, ()=>{
    const oauth2 = instagramOAuthClient();
    // Generate a random state verification cookie.
    const state = req.cookies.state || makeid(64);
    res.cookie("state", state.toString(), {maxAge: 3600000, secure: true, httpOnly: true});
    const redirectUri = oauth2.authorizeURL({
      client_id: functions.config().instagram.client_id,
      redirect_uri: `${req.protocol}://us-central1-le-maki-55.cloudfunctions.net/instagramCallback`,
      scope: OAUTH_SCOPES,
      state: state,
    });
    res.redirect(redirectUri);
  });
});

// instagramCallback函数
export const instagramCallback = functions.https.onRequest((req, res)=>{
  const oauth2 = instagramOAuthClient();
  return cookieParser()(req, res, ()=>{
    console.log(functions.config().instagram.client_id);
    fetch(req.url, {
      method: "POST",
      headers: {"Content-Type": "application/json", "client_id": functions.config().instagram.client_id},
      body: JSON.stringify({client_id: functions.config().instagram.client_id}),
    })
        .then((response) => response.json())
        .then((data) => {
          console.log("FETCH RESULT - body : "+data);
        });
    functions.logger.log("Received verification state:", req.cookies.state);
    functions.logger.log("Received state:", req.query.state);
    if (!req.cookies.state) {
      throw new Error("State cookie not set or expired. Maybe you took too long to authorize. Please try again.");
    } else if (req.cookies.state !== req.query.state) {
      throw new Error("State validation failed");
    }
    functions.logger.log("Received auth code:", req.query.code);
    if (req.query.code && req.query.code != "undefined") {
      const results = oauth2.getToken({
        code: req.query.code.toString(),
        redirect_uri: `${req.protocol}://us-central1-le-maki-55.cloudfunctions.net/instagramCallback`,
        scope: OAUTH_SCOPES,
      }).then((accessToken)=>{
        functions.logger.log("Auth code exchange result received:", results);
        // We have an Instagram access token and the user identity now.
        console.log("ACCESS TOKEN");
        console.log(accessToken);
        const access_Token = accessToken;
        const instagramUserID = accessToken.token.id;
        const profilePic = accessToken.token.profile_picture;
        const userName = accessToken.token.full_name;

        // Create a Firebase account and get the Custom Auth Token.
        createFirebaseAccount(instagramUserID, userName, profilePic, access_Token).then((token)=>{
          const firebaseToken = token;
          // Serve an HTML page that signs the user in and updates the user profile.
          return res.json({token: firebaseToken});
        });
      }, (error)=>{
        console.log(error);
      });
    } else {
      throw new Error("auth code exchange failed");
    }
  });
});

解决方案

问题根源

调用oauth2.getToken时未传入client_id和client_secret参数,这两个是Instagram OAuth2令牌交换的必填项;同时代码中多余的fetch请求完全无效,属于冗余操作。

修改后的回调函数代码

export const instagramCallback = functions.https.onRequest((req, res)=>{
  const oauth2 = instagramOAuthClient();
  return cookieParser()(req, res, ()=>{
    functions.logger.log("Received verification state:", req.cookies.state);
    functions.logger.log("Received state:", req.query.state);
    
    if (!req.cookies.state) {
      throw new Error("State cookie not set or expired. Maybe you took too long to authorize. Please try again.");
    } else if (req.cookies.state !== req.query.state) {
      throw new Error("State validation failed");
    }

    functions.logger.log("Received auth code:", req.query.code);
    if (req.query.code && req.query.code != "undefined") {
      // 补充令牌交换必填的client_id和client_secret参数
      oauth2.getToken({
        code: req.query.code.toString(),
        redirect_uri: `${req.protocol}://us-central1-le-maki-55.cloudfunctions.net/instagramCallback`,
        scope: OAUTH_SCOPES,
        client_id: functions.config().instagram.client_id,
        client_secret: functions.config().instagram.client_secret
      }).then((accessToken)=>{
        functions.logger.log("Auth code exchange result received:", accessToken);
        console.log("ACCESS TOKEN");
        console.log(accessToken);
        
        const access_Token = accessToken;
        const instagramUserID = accessToken.token.id;
        const profilePic = accessToken.token.profile_picture;
        const userName = accessToken.token.full_name;

        // 创建Firebase账户并获取自定义认证令牌
        createFirebaseAccount(instagramUserID, userName, profilePic, access_Token).then((token)=>{
          return res.json({token: token});
        });
      }, (error)=>{
        console.log(error);
      });
    } else {
      throw new Error("auth code exchange failed");
    }
  });
});

关键修改说明

  1. 移除冗余fetch请求:原代码中向自身发起的POST请求对令牌交换无任何帮助,直接删除即可
  2. 补充必填参数:在oauth2.getToken的参数对象中添加client_id和client_secret,确保与授权阶段使用的凭证一致
  3. 修正日志打印错误:将functions.logger.log中的results改为accessToken,避免打印未解析的Promise对象

另外需确认instagramOAuthClient()初始化时是否已配置凭证,如果初始化时未传入client_id和client_secret,则必须在每次调用getToken时手动补充,这也是本次报错的核心原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:47:37