【问题标题】:Get gmail address using Google Apps Script, Error: redirect_uri_mismatch使用 Google Apps 脚本获取 gmail 地址,错误:redirect_uri_mismatch
【发布时间】:2019-11-10 04:26:23
【问题描述】:

我尝试使用我的应用脚本获取用户的 gmail 地址。我咨询了几个地方:

https://developers.google.com/identity/sign-in/web/sign-in

https://developers.google.com/apps-script/guides/html/

在我之前发过但做不到的问题中又出现了新问题。

这个代码文件gs:

function doGet(e) {
  
 var tmp = HtmlService.createTemplateFromFile("testapi");
 return tmp.evaluate(); 
    
}

此代码文件html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="google-signin-client_id" content="1xxxxxxxxxx-xxxxxxxxi87eht.apps.googleusercontent.com">
    <title>Oauth2 web</title>

    <!-- Google library -->
    <script src="https://apis.google.com/js/platform.js" async defer></script>

    <!-- Jquery library to print the information easier -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>

    <!-- Bootstrap library for the button style-->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div id="profileinfo">
</div>
<div class="g-signin2" data-onsuccess="onSignIn"></div>

<script>
            function onSignIn(googleUser) {
              var profile = googleUser.getBasicProfile();
              console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
              console.log('Name: ' + profile.getName());
              console.log('Image URL: ' + profile.getImageUrl());
              console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.

              $("#profileinfo").append("<h2>Sup " + profile.getName() + ", welcome home my friend</h2>");
              $("#profileinfo").append("<img style='width:250px;height:250px' src='" + profile.getImageUrl() + "'><br><br>");
              $("#profileinfo").append("<p>Your email is: " + profile.getEmail() + "</p>");

            }
        </script>

<button type="button" class="btn btn-danger" onclick="signOut();">Sign out</button>

<script>
            function signOut() {
               var auth2 = gapi.auth2.getAuthInstance();
               auth2.signOut().then(function () {
                 console.log('User signed out.');
               $("#profileinfo").empty();
               $("#profileinfo").append("<h2>Goodbye old friend</h2>");
               });
            }
        </script>
</body>
</html>

【问题讨论】:

  • 引用确切的错误。
  • 好的,我已经编辑了

标签: javascript html google-apps-script google-signin


【解决方案1】:

在 Google Apps 脚本中创建的网络应用程序始终在 IFRAME 中提供,并且无法在 IFRAME 之外访问。

因此,标准的 Google 登录组件无法嵌入到这些应用中。

【讨论】:

  • 不正确。我试过一次,它奏效了。我认为起源/重定向也应该设置为script.googleusercontent.com。但它有效。
  • @theMaster 我尝试设置为 script.googleusercontent.com 但它也没有运行
  • @TheMaster 是啊!!!非常感谢 !感谢您的热情,我已经成功运行了^^
【解决方案2】:

我复制了您的步骤,它确实检索了 html,但是当您尝试登录时,在弹出窗口中抛出以下错误:

“Error: redirect_uri_mismatch

The JavaScript origin in the request, https://XXXXXXX-script.googleusercontent.com, does not match the ones authorized for the OAuth client.”

您需要从错误消息中复制 URL 并按照以下步骤操作:

1) 选择谷歌云中的项目并进入凭据 -> Oauth 同意屏幕,在授权域中添加“googleusercontent.com”。

2) 编辑您的凭据并将您之前获得的 URL 添加到“授权的 JavaScript 来源”部分。

3) 在新版本中部署为 Web 应用程序。

如果我理解正确,那应该可以,尽管有几点需要指出您如何部署 Web 应用程序:

1) 如果你设置部署选项以访问应用的用户身份执行应用,当你通过链接访问时,App脚本会提示自己的同意屏幕登录,然后当你点击登录时选项它会自动使用已经登录的用户登录。

2) 如果您将部署选项设置为像您一样执行应用程序并在访问选项中选择“任何人,甚至匿名”,当您单击登录选项时,它会提示您预期的 oauth 同意屏幕登录。唯一的事情是,当您退出并再次单击登录按钮时,它会自动使用以前的凭据登录(在普通服务器中,它会再次提示您同意屏幕)。

无需实现 Oauth,您可以将部署选项设置为“1)”中的设置,然后使用 App Script 中的 User 对象获取用户的电子邮件,尽管这是您可以从那里获得的唯一信息[1]。

[1]https://developers.google.com/apps-script/reference/base/user

【讨论】:

【解决方案3】:

如果我很了解您想要在前端获取电子邮件和用户个人资料信息,您不需要做所有这些复杂的事情。

在后台创建这个函数:

function getUser(){
  //Session.getEffectiveUser().getEmail(); // Just for scope
  var url = "https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
  var param = {
    method      : "Get",
    headers     : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
    'muteHttpExceptions' :true
  };
  var html = UrlFetchApp.fetch(url,param);
  var data = JSON.parse(html.getContentText());
  Logger.log(JSON.stringify(data))
  /* Result is JSON
  {"id":"Google User ID","email":"user@mail.com","verified_email":true,"picture":"https://xxxxxxxxxxxxxxxxx/photo.jpg"}
  */
  return data
}

那么现在你可以在前端调用这个函数来获取用户详细信息:

function getUserDetails(){
  google.script.run
        .withSuccessHandler(function(user) {
            //Do some stuffs with user details
            // Email is in user.email
          })
        .withFailureHandler(function(msg) {
            console.log(msg);
          })
        .getUser(); 
}

作为脚本请求 Session.getEffectiveUser().getEmail() 用户授予范围以允许获取用户信息。

然后您只需查询https://www.googleapis.com/oauth2/v1/userinfo?alt=json 端点即可获取用户详细信息。

史蒂芬

【讨论】:

  • 您提供的/oauth2/v1/userinfo 端点上的任何源/文档?
  • 它是 Google oauth2 文档的一部分,但无法找回。我用了很长时间,所以我复制粘贴代码。
  • 谢谢你帮助我,但它只能得到我的 gmail 地址。我想让所有用户在访问应用程序链接时使用我的应用程序
  • 无法从应用程序中执行此操作。唯一的解决方案是将这些信息存储在某处。可以是外部数据库、脚本属性等...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多