Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google authentication javascript

I'm trying to do a implementation of the google login on our website. I have read the documentation and setup a application on the apis console.

I prefer that the signup dialogue is shown in a popup and after the users logins in and accepts the permissions that I would get an javascript callback. This the api also supports according to the documentation. So I build the below with help of the documentation ;-)

This first part is to load the google client script async and the init the script with the correct clientid and apikey.

$gp = new googlePlus('@Trustpilot.Web.Social.Google.ClientID', '@Trustpilot.Web.Social.Google.ApiKey');
(function () {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/client.js?onload=googlePlusClientLoad';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();

The next part it the part that uses the google client api. handleClientLoad() is called when the client.js is loaded. The method checks if the use is authenticated. If the user is, the idea is that I want to login the user. If the user is not already authenticated there will be a button and when clicking handleAuthClick() is called, it basic does the same as handleClientLoad() but there will be an popup where the user most login (with google account) and accept permissions. After login handleAuthResult() is called which logins the user.

function googlePlus(clientId, apiKey) {
    this.clientId = clientId;
    this.apiKey = apiKey;
    this.scopes = 'https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email';

    /// This method is called when the javascript is loaded async
    this.handleClientLoad = function() {
        gapi.client.setApiKey(this.apiKey);
        window.setTimeout(this.authorize(true), 1);
    };

this.handleAuthResult = function (authResult) {
    console.log(authResult);
    if (authResult && !authResult.error) {
        var token = gapi.auth.getToken();
        console.log(token);
    }
    else if (authResult && authResult.error) {
        alert(authResult.error);
    }
};

this.handleAuthClick = function(event) {
    this.authorize(false);
    return false;
};

this.makeApiCall = function() {
    gapi.client.load('plus', 'v1', function () {
        var request = gapi.client.plus.people.get({
            'userId': 'me'
        });
        request.execute(function (resp) {
            console.log(resp);
        });
    });
};

    this.authorize = function (immediate) {
        gapi.auth.authorize({ client_id: this.clientId, scope: this.scopes, immediate: immediate }, this.handleAuthResult());
        //gapi.auth.authorize({ client_id: this.clientId, scope: this.scopes, immediate: immediate }, this.handleAuthResult());
    };
}
var googlePlusClientLoad = function() {
    $gp.handleClientLoad();
};

So now to the problem:

  1. When handleClientLoad is called the user is never authenticated even if the user already has autehnticated.
  2. If the user uses handleAuthClick() the popup shows and login, permissions and callback to handleAuthResult() work. But the parameter authResult is always nothing (should be something accouring to the documentation).
  3. If I try multiple times without reloading the page I can sometimes get the makeApiCall() and gapi.auth.getToken() to work and get the information I need.
like image 365
Ole Dallerup Avatar asked Sep 28 '12 17:09

Ole Dallerup


People also ask

Is gapi deprecated?

replace the deprecated Platform Library with the Identity Services library, and. if using the API Client Library, remove the deprecated gapi. auth2 module, its methods and objects, replacing them with Identity Services equivalents.

Is OAuth Authn or Authz?

OAuth is an authorization protocol. It is not designed for authentication. Yes, there is a step in the OAuth process where the identity server authenticates a resource owner. The way it happens does not belong to the OAuth protocol.


1 Answers

There are two issues in your code :

  • The API key is not required, you can remove it. You get the user token through OAuth2 and that is enough.
  • In authorize(), the handleAuthResult method is not correctly called, remove the parenthesis at the end of the function name. You do not want to execute the function, just pass its reference. Here's what the authorize method must look like :

    gapi.auth.authorize({ client_id: this.clientId, scope: this.scopes, immediate: immediate }, this.handleAuthResult);

Note the difference in parenthesis.

like image 154
David Avatar answered Sep 19 '22 12:09

David