Get gmail address using Google Apps Script, Error: redirect_uri_mismatch

I try 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

Answers:

Answer

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

Answer

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":"[email protected]","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

Answer

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.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.