"需要授权才能执行该操作"消息,即使在点击"允许"

时间:2018-03-26 12:41:39

标签: google-apps-script oauth-2.0 google-api google-oauth google-cloud-sql

我最近遇到了一个授权新的Google App Script项目的问题,特别是使用Cloud SQL管理API的项目。

先前授权的GAS项目中存在相同的代码,并且工作正常,但如果我第一次使用GAS项目的副本并尝试运行功能,则无法完成授权过程。我要浏览的屏幕如下:

  1. 需要授权。 - 点击"审核权限"
  2. 选择一个帐户来授权Google项目。 - 点击了我的帐户
  3. 此应用尚未经过验证! - 点击"转到项目 (不安全)"
  4. Google项目需要访问此范围列表.-点击"允许"
  5. 执行该操作需要授权。
  6. 警告屏幕(3)是该过程的最新补充。今年早些时候,当我创建和运营新项目时,我不会记得遇到它。我想知道Google最近是否对其OAuth2.0的安全实施做了任何更改。

    此外,此问题似乎只会影响对Cloud SQL管理API的REST调用。在上面提到的同一个项目中,我能够运行将数据写入同一个Google项目中的BigQuery表的函数,该项目也托管了Cloud SQL实例。显然,可以使一些范围和代码起作用。

    " https://www.googleapis.com/auth/sqlservice.admin"范围包含在我要求和批准的列表中。我甚至尝试手动编辑URL以添加更多的请求范围,但它仍然没有让我通过"需要授权来执行该操作"屏幕。

    有没有人有任何想法?

    编辑:

    触发身份验证的相关代码。

    // Function to get the ip address of a given CloudSQL instance
    function _getInstanceIpAddress_(projectId, sqlInstance) {
    
      var token = _getAuthenticationToken_();
    
      // Create the header authorisation  
      var headers = {
        "Authorization": "Bearer " + token
      };
    
      // Create the Cloud SQL instances get parameters
      var parameters = {
        "method": "get",    
        "headers": headers,
        "instance": sqlInstance,
        "project": projectId,
        "muteHttpExceptions": true
      };
    
      // Create the url of the sql instances get API    
      var api = "https://www.googleapis.com/sql/v1beta4/projects/" + projectId + "/instances/" + sqlInstance + "?fields=ipAddresses";   
    
      try {
        // Use the url fetch service to issue the https request and capture the response
        var response = UrlFetchApp.fetch(api, parameters);    
    
        // Extract the ip address of the instance from the response
        var content = JSON.parse(response.getContentText());
    
        return content.ipAddresses[0].ipAddress; 
      } catch(err) {
        _log_('ERROR', 'Getting ' + sqlInstance + ' instance ip address failed: ' + err);
        return null;
      }
    }
    
    function _getAuthenticationToken_() {
      // Check we have access to the service
      var service = getService();
      if (!service.hasAccess()) {
        var authorizationUrl = service.getAuthorizationUrl();
        _log_('INFO', 'Open the following URL and re-run the script: ' + authorizationUrl);
        return;
      }
    
      Logger.log('Passed Authentication');
    
      //Get the Access Token
      return service.getAccessToken();
    
      function getService() {
        // Create a new service with the given name. The name will be used when
        // persisting the authorized token, so ensure it is unique within the
        // scope of the property store.
        return OAuth2.createService('companyName-dev-service')
    
        // Set the endpoint URLs, which are the same for all Google services.
        .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
        .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    
        // Set the client ID and secret, from the Google Developers Console.
        .setClientId(CLIENT_ID)
        .setClientSecret(CLIENT_SECRET)
    
        // Set the name of the callback function in the script referenced
        // above that should be invoked to complete the OAuth flow.
        .setCallbackFunction('authCallback')
    
        // Set the property store where authorized tokens should be persisted.
        .setPropertyStore(PropertiesService.getUserProperties())
    
        // Set the scopes to request (space-separated for Google services).
        // this is admin access for the sqlservice and access to the cloud-platform:
        .setScope(
          'https://www.googleapis.com/auth/sqlservice.admin ' + 
          'https://www.googleapis.com/auth/cloud-platform')
    
        //Removed because this Should be covered by cloud-platform
        //'https://www.googleapis.com/auth/devstorage.read_write ' 
    
        // Below are Google-specific OAuth2 parameters.
    
        // Sets the login hint, which will prevent the account chooser screen
        // from being shown to users logged in with multiple accounts.
        .setParam('login_hint', Session.getActiveUser().getEmail())
    
        // Requests offline access.
        .setParam('access_type', 'offline')
    
        // Forces the approval prompt every time. This is useful for testing,
        // but not desirable in a production application.
        .setParam('approval_prompt', 'force');
      }
    
      function authCallback(request) {
        var cloudSQLService = getService();
        var isAuthorized = cloudSQLService.handleCallback(request);
    
        if (isAuthorized) {
          _log_('INFO', 'Access Approved');
          return HtmlService.createHtmlOutput('Success! You can close this tab.');
        } else {
          _log_('INFO', 'Access Denied');
          return HtmlService.createHtmlOutput('Denied. You can close this tab');
        }
      }
    }
    

2 个答案:

答案 0 :(得分:2)

如果你回想起大约一年前你可能还记得Massive Phishing Attack Targets Gmail Users你所看到的是谷歌对此的回应。

使用特定范围的网络凭据要求Google在除了创建相关凭据的开发人员之外的任何人可以使用它之前批准这些凭据。谷歌说,通常需要一周时间才能获得批准。

之前你没有看过,因为这只是最近点击了App脚本OAuth client verification

  

自2017年7月18日起,请求某些敏感OAuth范围的Google OAuth客户端将接受Google审核。

答案 1 :(得分:1)

我们在使用Google Compute Engine API时遇到了类似的问题。根据{{​​3}}在appsscript.json文件中显式设置范围为我们解决了这个问题:

"oauthScopes": [
    "https://www.googleapis.com/auth/spreadsheets.readonly",
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/script.container.ui",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/compute",
    "https://www.googleapis.com/auth/cloud-platform"
  ],

this article