32

I want to use "Login with Google" in my Phonegap App. I have read many articles but couldn't find out how it is done. Thanks in Advance. I tried using oAuth2 for "installed Applications" as per this URL. But then the app users have to manually copy code and paste in my app. I am using built.io Federated Login, if its relevant.

Augustus Francis
  • 2,694
  • 4
  • 22
  • 32

5 Answers5

43

Google has dropped support for the accepted answer above! After April 20th 2017 use of the In-App browser as described by @Deep Mehta will no longer be supported. If you use the accepted answer then it is going to start failing very soon.

Here's Google's post about the change: https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html

Luckily there's a new plugin that wraps up all the funcitonality that you need to do this:

https://github.com/EddyVerbruggen/cordova-plugin-googleplus and on NPM https://www.npmjs.com/package/cordova-plugin-googleplus

Here's an article on how to use it in Ionic 1 and 2 also: http://blog.ionic.io/google-oauth-changes

Again - DO NOT USE THE ACCEPTED ANSWER! It will fail after April 20 2017.

Alex
  • 619
  • 1
  • 8
  • 25
Nico Westerdale
  • 2,147
  • 1
  • 24
  • 31
  • Taurus, the latest commit on that plugin was 26 days ago. I would hardly call that abandoned. – Nico Westerdale Jul 29 '17 at 14:25
  • Okay, wrong choice of words. It is not very active, 5 issues in the last 25 days (the last one being mine) and not even of them has one comment. – doubleOrt Jul 30 '17 at 00:06
  • What the one you asked 11 hours ago? Sorry nobody is racing to help you on a Saturday. – Nico Westerdale Jul 30 '17 at 01:27
  • The one i asked 11 hours ago, and the other four issues raised within the last 25 days (none of which have any comments, meaning that they haven't been seen by the contributors). And to be honest, i did not notice the saturday thing because where i live, fridays are the weekends. – doubleOrt Jul 30 '17 at 01:31
  • Yeah and look at closed and you'll see that other issues have been closed. Look we all try and help out where we can, but this is a small plugin and there will always be open issues. Please don't go around saying a git repo isn't maintained when it is. You are spreading misinformation, especially as the accepted answer on this thread is going to cause a world of hurt to someone who doesn't see my post! – Nico Westerdale Jul 30 '17 at 01:39
  • Only one has been closed, the other 6, asked within the last 25 days, don't even have a single comment. And i know that it must be hard to keep up with all the opened issues when there are nearly 200 open issues, but the contributors should at least comment on the issues so that we know they have been seen, i currently don't know if i should use something else or wait for someone to participate. And if you take a look at my issue, you will see how weird everything is, i don't know what the issue is yet, but, if it is literally because of an alert, then the plugin is highly flawed :) – doubleOrt Jul 30 '17 at 01:55
  • But again, it is open source, so, thanks for the plugin i guess. – doubleOrt Jul 30 '17 at 01:56
  • Please answer this : https://stackoverflow.com/questions/49662677/phonegap-google-login-plugin-issue-error-4 – sqlchild Apr 05 '18 at 13:17
  • 2
    Google+ shutdown is not supposed to affect the plugin mentioned in the answer: https://github.com/EddyVerbruggen/cordova-plugin-googleplus/issues/555 – neno Apr 04 '19 at 10:33
31

add this code in one js file and include in your project. when you want to access google login api on button click call function callGoogle() rest will be done by this code. Dont forget to add your client id and Client_Secret keys. Its working fine for me. You need inappbrowser cordova plugin.

var googleapi = {
    authorize: function(options) {
        var deferred = $.Deferred();
         //Build the OAuth consent page URL
        var authUrl = 'https://accounts.google.com/o/oauth2/auth?' + $.param({
            client_id: options.client_id,
            redirect_uri: options.redirect_uri,
            response_type: 'code',
            scope: options.scope
        });

        //Open the OAuth consent page in the InAppBrowser
        var authWindow = window.open(authUrl, '_blank', 'location=no,toolbar=no');

        //The recommendation is to use the redirect_uri "urn:ietf:wg:oauth:2.0:oob"
        //which sets the authorization code in the browser's title. However, we can't
        //access the title of the InAppBrowser.
        //
        //Instead, we pass a bogus redirect_uri of "http://localhost", which means the
        //authorization code will get set in the url. We can access the url in the
        //loadstart and loadstop events. So if we bind the loadstart event, we can
        //find the authorization code and close the InAppBrowser after the user
        //has granted us access to their data.
        $(authWindow).on('loadstart', function(e) {
            var url = e.originalEvent.url;
            var code = /\?code=(.+)$/.exec(url);
            var error = /\?error=(.+)$/.exec(url);

            if (code || error) {
                //Always close the browser when match is found
                authWindow.close();
            }

            if (code) {
                //Exchange the authorization code for an access token
                $.post('https://accounts.google.com/o/oauth2/token', {
                    code: code[1],
                    client_id: options.client_id,
                    client_secret: options.client_secret,
                    redirect_uri: options.redirect_uri,
                    grant_type: 'authorization_code'
                }).done(function(data) {
                    deferred.resolve(data);

                    $("#loginStatus").html('Name: ' + data.given_name);
                }).fail(function(response) {
                    deferred.reject(response.responseJSON);
                });
            } else if (error) {
                //The user denied access to the app
                deferred.reject({
                    error: error[1]
                });
            }
        });

        return deferred.promise();
    }
};
var accessToken;
var UserData = null;

function callGoogle() {

    //  alert('starting');
    googleapi.authorize({
        client_id: 'client_id',
        client_secret: 'Client_Secret',
        redirect_uri: 'http://localhost',
        scope: 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email'
    }).done(function(data) {
        accessToken = data.access_token;
        // alert(accessToken);
        // $loginStatus.html('Access Token: ' + data.access_token);
        console.log(data.access_token);
        console.log(JSON.stringify(data));
        getDataProfile();

    });

}

// This function gets data of user.
function getDataProfile() {
    var term = null;
    //  alert("getting user data="+accessToken);
    $.ajax({
        url: 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=' + accessToken,
        type: 'GET',
        data: term,
        dataType: 'json',
        error: function(jqXHR, text_status, strError) {},
        success: function(data) {
            var item;

            console.log(JSON.stringify(data));
            // Save the userprofile data in your localStorage.
            localStorage.gmailLogin = "true";
            localStorage.gmailID = data.id;
            localStorage.gmailEmail = data.email;
            localStorage.gmailFirstName = data.given_name;
            localStorage.gmailLastName = data.family_name;
            localStorage.gmailProfilePicture = data.picture;
            localStorage.gmailGender = data.gender;
        }
    });
    disconnectUser();
}

function disconnectUser() {
    var revokeUrl = 'https://accounts.google.com/o/oauth2/revoke?token=' + accessToken;

    // Perform an asynchronous GET request.
    $.ajax({
        type: 'GET',
        url: revokeUrl,
        async: false,
        contentType: "application/json",
        dataType: 'jsonp',
        success: function(nullResponse) {
            // Do something now that user is disconnected
            // The response is always undefined.
            accessToken = null;
            console.log(JSON.stringify(nullResponse));
            console.log("-----signed out..!!----" + accessToken);
        },
        error: function(e) {
            // Handle the error
            // console.log(e);
            // You could point users to manually disconnect if unsuccessful
            // https://plus.google.com/apps
        }
    });
}
Tianzhen Lin
  • 2,404
  • 1
  • 19
  • 19
Deep Mehta
  • 1,250
  • 1
  • 16
  • 29
  • Hi Deep, Did same thing. stuck with a window with message "Please copy this code, swith to application and paste it there". Please help !!!. – Manesh Appukuttan Jun 11 '14 at 12:35
  • Hi Deep, I created client id as Installed Application -> Other. And got redirected URI as urn:ietf:wg:oauth:2.0:oob . Please let me know is dis the correct way of doing? – Manesh Appukuttan Jun 11 '14 at 12:59
  • get back to you soon. but if u r in mobile the i think localhost will do. but let me check – Deep Mehta Jun 11 '14 at 13:08
  • Hi Deep, Found out the solution.. It will works up to android version 17. Not for Kit Kat. – Manesh Appukuttan Jun 18 '14 at 09:02
  • Has there been any updates with this? Were you able to use OAuth using cordova? – Owen McAlack Feb 17 '15 at 12:16
  • PXdty : I have not tried since a while. But it should work as its based upon standard way of using Google+ API. If you find any issue let me know will solve it. – Deep Mehta Feb 19 '15 at 18:28
  • Yes, any workaround for not including the secret in a .js file? – Toni Michel Caubet Jun 22 '15 at 11:02
  • Add in config file or create system variable. – Deep Mehta Jun 22 '15 at 14:17
  • 1
    I spent lot of time to find the solution but it's by far best and simple. Thanks! – immayankmodi Aug 05 '15 at 09:42
  • @MM Tac: I am glad that i was able to help you out. feel free to upvote ;) – Deep Mehta Aug 05 '15 at 16:08
  • @DeepMehta, what should be the redirect URL? I'm using `http://localhost` for app. – immayankmodi Aug 07 '15 at 06:36
  • Yea localhost mostly. – Deep Mehta Aug 07 '15 at 06:37
  • 1
    @DeepMehta, okay thanks. Now I've only one issue that It's asking for permissions every time while we are clicking on sign in button. It should ask for accept permission only first time and then it'll automatically take permission and not ask again. Is there any way while clicking sign in button it'll load pre-fill emailid's from mobile? – immayankmodi Aug 11 '15 at 06:15
  • I dont think it will be proper way of doing. i would let user sign in once and refresh token once it gets expired unless he logout from application settings. – Deep Mehta Aug 11 '15 at 16:41
  • @DeepMehta : I followed your approach in one of my app & it's working fine. Just one issue, I'm getting is... If I've already logged in 3 other gmail accounts with my gmail native app... It's not giving me any option to choose any one from them. I've posted about this Stackoverflow at : http://stackoverflow.com/questions/33481944 – Suresh Nov 03 '15 at 10:41
  • Hello @DeepMehta I have used your code and from google provided code also but the problems after login complete it doesn't coming back to the app from opened popup. please refer this link I have done same thing but the only problem is it doesn't let me go on my app - http://stackoverflow.com/questions/34135466/coming-url-doesnt-let-me-go-further-in-cordova-app-after-google-authentication – Mahavirsinh Padhiyar Dec 09 '15 at 05:36
  • @MMTac Did you find any solution for the "accept permission everytime" problem which you mentioned in the comments? – Reza Dec 29 '15 at 19:50
  • @RezaRahmati no actually, I don't tried more due to work load so I left that project and moved to another project. Sorry but this is the fact! – immayankmodi Jan 10 '16 at 17:00
  • 15
    DO NOT DO THIS! If you put your client secret in your app, it doesn't matter whether it is in a config file or hardcoded, PEOPLE WILL ACCESS IT. If someone gains access to your client secret they can act as though they are your app, consume your API limits and generally give you a very bad day. – Rich Jun 01 '16 at 07:22
  • I use this for ionic app and getting 403 Error:disallowed_useragent http://stackoverflow.com/questions/40591090/403-error-thats-an-error-error-disallowed-useragent. any solution for this? working good with Android. – Sohan Nov 19 '16 at 12:49
  • http://stackoverflow.com/questions/40591090/403-error-thats-an-error-error-disallowed-useragent – Deep Mehta Nov 19 '16 at 21:26
  • @DeepMehta : Please answer this : https://stackoverflow.com/questions/49662677/phonegap-google-login-plugin-issue-error-4 – sqlchild Apr 05 '18 at 13:15
5

I recommend this cordova plugin: https://www.npmjs.com/package/cordova-plugin-googleplus It's pretty recent but I just added it to my app and it seems to do the trick!

ldeluca
  • 934
  • 3
  • 12
  • 25
  • @Ideluca : Please answer this : https://stackoverflow.com/questions/49662677/phonegap-google-login-plugin-issue-error-4 – sqlchild Apr 05 '18 at 13:18
  • How did you made this plugin work in your app ? Did it worked flawlessly and is it successful ? How did you check whether the user is already logged in on app opening, there ain't any flag mentioned in the doc on github – sqlchild Apr 05 '18 at 13:20
5

It's 2019: and Google+ API is shut down.

Google has an article about how to authenticate using the firebase API.

10 Rep
  • 2,217
  • 7
  • 19
  • 33
Alex
  • 619
  • 1
  • 8
  • 25
0

Another implementation that works well here: https://github.com/valenzia10/PhonegapGoogleLogin

Jason Washo
  • 536
  • 6
  • 22
  • Hi Jason Washo,I have used above link,Google Login is working fine, need to get the user details.Help me please ASAP.Thanks in Advance – Naveen Dec 16 '16 at 09:46
  • What details do you need? Usually the scopes define what level of information about the user is accessible. – Jason Washo Dec 16 '16 at 17:31
  • I need to get the user Information like Email,Name.Just a basic info of the user.Please help me Jason Washo. – Naveen Dec 19 '16 at 07:01