How to implement Google OAuth in an Ionic 2 app?

I need to add Google login in my Ionic v2 app.

Currently I cannot use the Ionic Authentication service because it’s not ready for v2 yet.

I’ve also tried the ng2-cordova-oauth plugin but I cannot use ionic serve or Ionic View to test the authentication which is a huge inconvenience for me because I no longer have an easy way to show the app to the client.

So… any alternative?

Also posted this question on Stack Overflow.

Have you tried with firebase auth?

Actually I’ve came across this blog that explains how to do that but I thought that having to register an account in Firebase just for that was a bit of overkill. I might give it a try anyways if I can’t find a better solution.

Well, firebase is good for testing a lot of things with database and auth. I tried with the same tutorial and is working fine (from the browser too).

2 Likes

Pop up is a no go. Does not with ios chrome which is half of my app’s access origin. I has been failing on android mashmallow as afar as I can tell.

You can implement Google OAuth in Ionic 2 with plain JavaScript and no third-party libraries. Note, however, that you will need to branch your logic at runtime depending on whether you are running on a device (using InAppBrowser) or in a browser (e.g. via ionic serve). To use Google OAuth you just need to

  1. set allowed origins and redirects (matching your expected value of window.location.origin) for your app in the Google Developers Console
  2. construct the OAuth GET request, setting ‘redirect_uri’ to window.location.origin and target to _self for browser-based auth. If running InAppBrowser on device, target should be _blank since Google OAuth will not redirect to file-based URLs. You could also use ng2-cordova-oauth for the device version.
  3. parse the hash fragment of the redirected URL. In particular, you will need the access_token portion, but may want other token info, such as expiry, etc.

Here is an example AuthService I am injecting into my Ionic 2 app to enable Google OAuth:

import {Injectable} from 'angular2/core';
import {Location} from 'angular2/router';

@Injectable()
export class AuthService {
    token: any;

    constructor(loc?: Location) {
        // TODO: replace current token if hash token is newer, unexpired
        if (window.location.hash.match(/^#access_token/) && ! this.token) {
            this.parseToken();
            loc.go('/');
        }
        else if (this.token) {
            console.log('found token: ', this.token);
        }
    }
    
    call() {
        // build authUrl:
        var authBase = 'https://accounts.google.com/o/oauth2/v2/auth';
        var authParams = {
            response_type: 'token',
            client_id: '[MY-APP-CLIENT-ID].apps.googleusercontent.com',
            redirect_uri: window.location.origin,
            scope: [ // MY AUTH SCOPE(S)
            ].join(' ')
        };
        var params = [];
        for (var k in authParams) {
            params.push(k + '=' + authParams[k]);
        }
        var authUrl = authBase + '?' + params.join('&');
        window.open(authUrl, '_self');
    }

    // TODO: move this to Token constructor?  Token(location.hash)
    parseToken() {
        this.token = {
            created: new Date().getTime()
        }
        var parmStr = location.hash.substring(1); // strip leading hash
        var parms = parmStr.split('&');
        for (var i in parms) {
            var kv = parms[i].split('=');
            this.token[kv[0]] = kv[1];
        }
    }
}
3 Likes

I try to using your code but get error when run on device emulator.

The callback URL is like file:/// and not localhost

Any suggestion to fix this?