0

I try to get gmail address of user use my app script. I have consulted several places :

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

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

and in the question I posted before but can't do it and there's a new problem.

This code file gs:

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

This code file 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>

create clientID console.developers.google.com

URL of Apps script

error

Marios
  • 26,333
  • 8
  • 32
  • 52
Naoa Lee
  • 135
  • 2
  • 19

3 Answers3

1

I reproduced your steps, and it does retrieve the html but when you try to sign in, the following error is thrown in a pop-up window:

“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.”

You need to copy the URL from the error message and follow these steps:

1) Select the project in google cloud and go to credentials -> Oauth consent screen , in authorized domains add “googleusercontent.com”.

2) Edit your credentials and add the URL you got before to the “Authorized JavaScript origins” part.

3) Deploy as a web app in a new version.

If I understood right, that should work, although a couple of things to point out on how you deploy the web app:

1) If you set the deploy options to execute the app as the user accessing the app, when you access with the link, App script will prompt its own consent screen to log in, then when you click on the sign-in option it’ll automatically sign-in with the user that’s already logged.

2) If you set the deploy options to execute the app as you and in the access option you select “Anyone, even anonymous”, when you click on the sign-in option it’ll prompt you the expected oauth consent screen to log in. The only thing is that when you sign-out and click on sign-in button again, it’ll automatically log in with the previous credentials (In a normal server it would prompt you the consent screen again).

Without the need of implementing Oauth, you can set the deployment options as the setup in “1)”, and then use the User object from App Script to obtain the user’s email, although that’s the only information you can get from there [1].

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

Andres Duarte
  • 3,166
  • 1
  • 7
  • 14
  • I have followed those still not, still report the same error – Naoa Lee Jun 30 '19 at 13:30
  • " Error: redirect_uri_mismatch The JavaScript origin in the request, https://n-km7qohnnyveic6axc5yz7fxl3kxnmktgzbcoi7i-0lu-script.googleusercontent.com, does not match the ones authorized for the OAuth client. " --> i don't know link request Where did it created from ? – Naoa Lee Jun 30 '19 at 13:33
  • this link "https://n-km7qohnnyveic6axc5yz7fxl3kxnmktgzbcoi7i-0lu-script.googleusercontent.com" – Naoa Lee Jun 30 '19 at 13:35
  • I don’t know either where the URL is created from, but you have to add it entirely from https:// until the end, in the authorized javascript origins inputs. – Andres Duarte Jun 30 '19 at 19:07
  • Thanks you so much ! I have run it successfully ^^ – Naoa Lee Jun 30 '19 at 19:47
1

If I well understand you want to get in frontend the email and user profile information you don't need to do all this complex things.

In backend create this function :

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
}

Then now in frontend you can call this function to get in the user details :

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(); 
}

As the script request the Session.getEffectiveUser().getEmail() the user grant scope to allow to get user information.

Then you just have to query the https://www.googleapis.com/oauth2/v1/userinfo?alt=json endpoint to get user details.

Stéphane

St3ph
  • 2,232
  • 17
  • 17
  • Any source/documentation on the `/oauth2/v1/userinfo` endpoint you provided? – TheMaster Jun 29 '19 at 07:46
  • It is part of the Google oauth2 documentation but can't find it back. I use it since long time so I copy paste Code. – St3ph Jun 29 '19 at 08:10
  • Thanks you help me but it get only my gmail address . I want get all user use my app when they access the link of the app – Naoa Lee Jun 30 '19 at 10:39
  • It is not possible to do that from the application. Only solution is to store this information somewhere. Can be external database, script properties, etc... – St3ph Jul 01 '19 at 11:08
-1

Web Apps created inside Google Apps Script are always served inside an IFRAME and cannot be accessed outside the IFRAME.

Therefore the standard Google sign-in component cannot be embedded into these apps.

Amit Agarwal
  • 10,910
  • 1
  • 32
  • 43
  • Not true. I tried once and it worked. I think the origins/redirect should also be set to `script.googleusercontent.com`. But it works. – TheMaster Jun 28 '19 at 13:51
  • @theMaster i try set to script.googleusercontent.com but it also not run – Naoa Lee Jun 30 '19 at 13:04
  • @TheMaster yeah!!! Thanks you so much ! Thanks for your enthusiasm, I have run it successfully ^^ – Naoa Lee Jun 30 '19 at 14:47