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

Streamlit集成Google Drive Picker OAuth2遇400 invalid_request错误求助

解决Streamlit集成Google Drive Picker的OAuth 400错误问题

问题描述

我正在用Python开发Streamlit应用,需要集成Google Drive Picker API实现用户文件选择功能。因为不熟悉JavaScript,直接采用了官方的Google Picker + OAuth2示例代码。

已完成的配置操作:

  • 创建Web应用类型的OAuth Client ID
  • 将ngrok生成的HTTPS URL设置为授权来源和重定向URI
  • 引入Google Identity Services和Picker API脚本
  • 尝试调整Picker代码中的.build()与.toUri()写法
  • 在Google Cloud项目中启用Drive API

但始终遇到错误:Error 400: invalid_request - 无法登录此应用,因为它不符合Google OAuth 2.0安全政策。由于主要技术栈是Python和Streamlit,调试JavaScript OAuth流程存在困难,求有相关集成经验的人帮忙解决该OAuth错误。

当前使用的代码

picker_html = f"""
<html>
    <script type="text/javascript">
      const CLIENT_ID = "{client_id}";
      const API_KEY = "{api_key}";
      const APP_ID = "{app_id}";
      const SCOPES = 'https://www.googleapis.com/auth/drive.readonly';

      let accessToken = null;
      let tokenClient;

      function gapiLoaded() {{
        gapi.load('client:picker', initializePicker);
      }}

      async function initializePicker() {{
        await gapi.client.load('https://www.googleapis.com/discovery/v1/apis/drive/v3/rest');
        document.getElementById('auth_button').style.display = 'block';
      }}

      function gisLoaded() {{
        tokenClient = google.accounts.oauth2.initTokenClient({{
          client_id: CLIENT_ID,
          scope: SCOPES,
          callback: (tokenResponse) => {{
            if (tokenResponse.error) {{
              alert("Error during token request");
              return;
            }}
            accessToken = tokenResponse.access_token;
            createPicker();
          }}
        }});
      }}

      function requestAccess() {{
        if (!accessToken) {{
          tokenClient.requestAccessToken({{ prompt: 'consent' }});
        }} else {{
          createPicker();
        }}
      }}

      function createPicker() {{
        const view = new google.picker.View(google.picker.ViewId.DOCS);
        const pickerBuilder = new google.picker.PickerBuilder()
          .enableFeature(google.picker.Feature.NAV_HIDDEN)
          .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
          .setAppId(APP_ID)
          .setOAuthToken(accessToken)
          .setDeveloperKey(API_KEY)
          .addView(view)
          .addView(new google.picker.DocsUploadView())
          .setCallback(pickerCallback);

        const picker = pickerBuilder.build();  // Build separately!
        picker.setVisible(true);
      }}

      function pickerCallback(data) {{
        if (data.action === google.picker.Action.PICKED) {{
          const file = data.docs[0];
          document.getElementById("output").innerText =
            "📄 Fichier sélectionné: " + file.name + "\n🆔 ID: " + file.id;
        }}
      }}

      window.onload = function () {{
        // Start loading once HTML is ready
        gapiLoaded();
        gisLoaded();
      }};
    </script>

    <style>
      #auth_button {{
        display: none;
        padding: 12px 24px;
        background-color: #4285f4;
        color: white;
        font-size: 16px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
      }}
    </style>
  </head>
  <body>
    <button id="auth_button" onclick="requestAccess()">📁 Open Google Picker</button>
    <pre id="output" style="margin-top: 20px"></pre>
  </body>
</html>
"""

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 18:52:42