Google Workspace日历会议解决方案的OAuth2集成失败,出现CORS重定向问题。

huangapple go评论76阅读模式
英文:

Google Workspace Add-on for Calendar Conference Solution with OAuth2 integration fails on redirect with CORS

问题

我已经构建了一个谷歌工作区插件,用于日历会议解决方案,使用了应用脚本和oauth2库。

我的 OAuth 客户端代码如下:

return (
    OAuth2.createService("OAuthApp")
      // 设置授权基础 URL。
      .setAuthorizationBaseUrl(`${FRONTEND_DOMAIN}/auth/login`) // 前端 API
      .setTokenUrl(`${BACKEND_DOMAIN}/v1.0/oauth/exchange-code-for-token`) // 后端 API

      // 设置客户端 ID 和秘密。
      .setClientId(CLIENT_ID)
      .setClientSecret(CLIENT_SECRET)

      // 设置应完成 OAuth 流程的回调函数的名称。
      .setCallbackFunction("authCallback")

      // 设置用于存储已授权令牌的属性存储。
      .setPropertyStore(PropertiesService.getUserProperties())
      .setCache(CacheService.getUserCache())
      .setLock(LockService.getUserLock())
);

其中,对于 setAuthorizationBaseUrl,我提供了前端页面,以打开用户进行身份验证的登录页面。当用户成功进行身份验证后,后端将在参数中附带授权代码,以状态码 302 重定向到插件的 https://script.google.com/macros/d/{SCRIPT_ID}/usercallback

然而,当我从后端将前端重定向到插件时,控制台出现以下错误:

Access to XMLHttpRequest at 'https://script.google.com/macros/d/{SCRIPT_ID}/usercallback?code=4611729c041e9d0f93506bcfa772707d' (redirected from 'https://{BACKEND_ENDPOINT}/oauth/verify-otp') from origin 'https://{FRONTEND_ENDPOINT}' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我的插件清单如下:

{
  "oauthScopes": [
    "https://www.googleapis.com/auth/calendar.addons.execute",
    "https://www.googleapis.com/auth/calendar.events.readonly",
    "https://www.googleapis.com/auth/calendar.addons.current.event.read",
    "https://www.googleapis.com/auth/calendar.addons.current.event.write",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/script.scriptapp"
  ],
  "addOns": {
    "common": {
      "homepageTrigger": {
        "enabled": false
      },
      "logoUrl": "https://lh3.googleusercontent.com/-WuPhRsFGKUc/XCng7m_FIxI/AAAAAAAAAGg/ASH4GCGDMs0d55OZQGCSIQHXjRAKnkeTQCLcBGAs/s400/jitsi-logo-96x96.png",
      "name": "Conference App"
    },
    "calendar": {
      "conferenceSolution": [
        {
          "id": 1,
          "name": "Private Meeting",
          "logoUrl": "https://lh3.googleusercontent.com/-WuPhRsFGKUc/XCng7m_FIxI/AAAAAAAAAGg/ASH4GCGDMs0d55OZQGCSIQHXjRAKnkeTQCLcBGAs/s400/jitsi-logo-96x96.png",
          "onCreateFunction": "createPrivateMeeting"
        }
      ],
      "currentEventAccess": "READ_WRITE"
    }
  },
  "timeZone": "America/New_York",
  "runtimeVersion": "V8",
  "dependencies": {
    "enabledAdvancedServices": [
      {
        "userSymbol": "Calendar",
        "serviceId": "calendar",
        "version": "v3"
      }
    ],
    "libraries": [
      {
        "userSymbol": "OAuth2",
        "version": "43",
        "libraryId": "1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF"
      }
    ]
  },
  "webapp": {
    "access": "ANYONE",
    "executeAs": "USER_ACCESSING"
  },
  "exceptionLogging": "STACKDRIVER"
}

从网络请求看,浏览器在从后端重定向到 Google 脚本时进行了预检请求,并因跨域问题失败。我尝试将标头中的 Content-Type 更改为 text/plain;charset=utf-8 以避免预检请求,但跨域问题仍然存在。

我期望弹出窗口会被重定向到插件,并交换授权代码以获取授权令牌。

英文:

I have built a google workspace addon for calendar conference solution using app script and oauth2 library.

My oauth client code is:

return (
    OAuth2.createService("OAuthApp")
      // Set the endpoint URLs.
      .setAuthorizationBaseUrl(`${FRONTEND_DOMAIN}/auth/login`) // frontend api
      .setTokenUrl(`${BACKEND_DOMAIN}/v1.0/oauth/exchange-code-for-token`) // backend api

      // Set the client ID and secret.
      .setClientId(CLIENT_ID)
      .setClientSecret(CLIENT_SECRET)

      // Set the name of the callback function that should be invoked to
      // complete the OAuth flow.
      .setCallbackFunction("authCallback")

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties())
      .setCache(CacheService.getUserCache())
      .setLock(LockService.getUserLock())
  );

Where for setAuthorizationBaseUrl i have provided out frontend page to open login page for user to authenticate. When user authenticates successfully, backend redirects to the addon on https://script.google.com/macros/d/{SCRIPT_ID}/usercallback with auth code in params and status code 302.

However when i redirect the frontend to addon from backend i get this error in console:

Access to XMLHttpRequest at 'https://script.google.com/macros/d/{SCRIPT_ID}/usercallback?code=4611729c041e9d0f93506bcfa772707d' (redirected from 'https://{BACKEND_ENDPOINT}/oauth/verify-otp') from origin 'https://{FRONTEND_ENDPOINT}' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

My add on manifest is:

{
  "oauthScopes": [
    "https://www.googleapis.com/auth/calendar.addons.execute",
    "https://www.googleapis.com/auth/calendar.events.readonly",
    "https://www.googleapis.com/auth/calendar.addons.current.event.read",
    "https://www.googleapis.com/auth/calendar.addons.current.event.write",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/script.scriptapp"
  ],
  "addOns": {
    "common": {
      "homepageTrigger": {
        "enabled": false
      },
      "logoUrl": "https://lh3.googleusercontent.com/-WuPhRsFGKUc/XCng7m_FIxI/AAAAAAAAAGg/ASH4GCGDMs0d55OZQGCSIQHXjRAKnkeTQCLcBGAs/s400/jitsi-logo-96x96.png",
      "name": "Conference App"
    },
    "calendar": {
      "conferenceSolution": [
        {
          "id": 1,
          "name": "Private Meeting",
          "logoUrl": "https://lh3.googleusercontent.com/-WuPhRsFGKUc/XCng7m_FIxI/AAAAAAAAAGg/ASH4GCGDMs0d55OZQGCSIQHXjRAKnkeTQCLcBGAs/s400/jitsi-logo-96x96.png",
          "onCreateFunction": "createPrivateMeeting"
        }
      ],
      "currentEventAccess": "READ_WRITE"
    }
  },
  "timeZone": "America/New_York",
  "runtimeVersion": "V8",
  "dependencies": {
    "enabledAdvancedServices": [
      {
        "userSymbol": "Calendar",
        "serviceId": "calendar",
        "version": "v3"
      }
    ],
    "libraries": [
      {
        "userSymbol": "OAuth2",
        "version": "43",
        "libraryId": "1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF"
      }
    ]
  },
  "webapp": {
    "access": "ANYONE",
    "executeAs": "USER_ACCESSING"
  },
  "exceptionLogging": "STACKDRIVER"
}

From the network it seems the browser makes a preflight request when redirected from the backend to the google script and fails with cors error.
I tried to change the Content-Type in headers to text/plain;charset=utf-8 to avoid the preflight request but the cors issue still persists.

I am expecting the popup to get redirect to addon and exchange the auth code for auth token.

答案1

得分: 1

我犯的错误是将弹出窗口从后端重定向到 appscript。而不是从后端返回带有授权码连接到弹出窗口/前端的重定向 URI,并前端重定向,从而修复跨域不匹配错误。

英文:

The mistake i was making was redirecting the popup to appscript from backend. Instead of returning the redirect uri with auth code concatenated in response from the backend to the popup/frontend and frontend redirects which fixes the cors mismatch error.

huangapple
  • 本文由 发表于 2023年2月16日 19:41:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75471749.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定