Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google sign-in using Javascript API without triggering popup

I am using following code for users to be able to login using their Google account via Javascript API.

HTML

<a id="gp_login" href="javascript:void(0)" onclick="javascript:googleAuth()">Login using Google</a>

Javascript

function gPOnLoad(){
     // G+ api loaded
     document.getElementById('gp_login').style.display = 'block';
}
function googleAuth() {
    gapi.auth.signIn({
        callback: gPSignInCallback,
        clientid: googleKey,
        cookiepolicy: "single_host_origin",
        requestvisibleactions: "http://schema.org/AddAction",
        scope: "https://www.googleapis.com/auth/plus.login email"
    })
}

function gPSignInCallback(e) {
    if (e["status"]["signed_in"]) {
        gapi.client.load("plus", "v1", function() {
            if (e["access_token"]) {
                getProfile()
            } else if (e["error"]) {
                console.log("There was an error: " + e["error"])
            }
        })
    } else {
        console.log("Sign-in state: " + e["error"])
    }
}

function getProfile() {
    var e = gapi.client.plus.people.get({
        userId: "me"
    });
    e.execute(function(e) {
        if (e.error) {
            console.log(e.message);
            return
        } else if (e.id) {
            // save profile data
        }
    })
}(function() {
    var e = document.createElement("script");
    e.type = "text/javascript";
    e.async = true;
    e.src = "https://apis.google.com/js/client:platform.js?onload=gPOnLoad";
    var t = document.getElementsByTagName("script")[0];
    t.parentNode.insertBefore(e, t)
})()

This code is working fine. I want to use the above code (using Javascript) to login user from their Google account without triggering a popup window. Like, user clicks the login link, asked for app permissions in the same window/tab, user grants permission, user redirected back to the page where Google login link was, profile data is saved and user is logged in.

like image 318
terriblecoder45 Avatar asked Jan 12 '15 15:01

terriblecoder45


2 Answers

You can the use ux_mode parameter (options are 'redirect' or 'popup') and set a redirect_uri if you want to redirect to a different page.

It's also necessary to authorize the URL for the OAuth client on your google project page.

  function initClient() {
    gapi.client.init({
      apiKey: API_KEY,
      clientId: CLIENT_ID,
      discoveryDocs: DISCOVERY_DOCS,
      scope: SCOPES,
      ux_mode: 'redirect',
      //redirect_uri: custom url to redirect'
    }).then(function () {
      // Listen for sign-in state changes.
      gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

      // Handle the initial sign-in state.
      updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
      authorizeButton.onclick = handleAuthClick;
      signoutButton.onclick = handleSignoutClick;
    });
  }
like image 59
default Avatar answered Nov 20 '22 04:11

default


Such functionality is not provided through Google API. You should stick with gapi.auth.signIn. I know just one way to make it work, but it's very hacky.

gapi.auth.signIn opens authentication window. Save authentication window url in your app1. Instead of calling gapi.auth.signIn, redirect user to that url.

To redirect successful authentication back to your website, add/modify redirect_url param in the url2. Keep in mind that redirect_uri must be registered in developers console.

Example: https://accounts.google.com/o/oauth2/auth?client_id=1234567890.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.login&immediate=false&response_type=token&redirect_uri=http://example.com

This way google will redirect user back to your website. access_token is provided through GET params.

1If google changes their API this may break (since this method bypasses JS API and assumes that all those params in the url will be supported for ever).

2Redirect_url is introduced in offline access flow documentation. I don't think this param was intended to work in any other cases.

I strongly advise not to use this idea (since it bypasses JS API and uses undocumented functionality). Stick with gapi.auth.signIn.

like image 34
Jarosław Gomułka Avatar answered Nov 20 '22 03:11

Jarosław Gomułka