OAuth Login

I setup a local node.js server that handles OAuth authentication by using PassportJS. Basically the user clicks on a button and the following redirection are done:

example.com/auth/google -> Google Sign In process -> Google redirect to example.com/auth/google/return -> PassportJS process the authentication returned by Google -> final redirection to / if success

It works fine in a browser but would this kind of process work in a mobile app?

I first tried to redirect to my local server but I get an ERR_CONNECTION_TIMED_OUT.

      <ion-content>
		<button ng-click="redirectTo('http://example.com:3000/auth/google')">OAuth</button>
      </ion-content>

and the controller code

	$scope.redirectTo = function (path) {
			$window.location.href = path;
        };

i would suggest you try it using the iappbrowser plugin

The problem is that your sever is a web server, and in the browser, it can redirect your web app during the OAuth process. When using your server with a mobile app, the server acts as a restful server, it does not server your static assets, the phone loads them up. Passport also uses cookies and sessions which may not be the best solution when implementing auth with your mobile app. A better approach is to use client side authentication using the cordova inAppBrowser. Take a look at this example of how I am achieving OAuth with with Beats Music API, this is specific to Beats Music but the process is the same for all OAuth 2. I’m using Beats music client side auth, if you;re using server side auth, then instead if receiving the user’s access_token, you’ll receive an exchange token you must use to request the access token, just an extra step that you’ll have to take using $http.

.factory('LoginService', function (localStorageService, $window, Beats, $state) {
  var url = Beats.authorize + '?response_type=token&' + 'redirect_uri=' + Beats.callback + '&client_id=' + Beats.key;
  var loginWindow;
  var parser;
  var params;
  var token;
  return {
    login: function () {
      loginWindow = $window.open(url, '_blank', 'location=no,toolbar=no');
      loginWindow.addEventListener('loadstart', function (evt) {
        parser = $window.document.createElement('a');
        parser.href = evt.url;
        params = parser.search.split('&');

        angular.forEach(params, function (param) {
          if(param.indexOf('access_token') > -1) {
            token = param.substring(13);
            if(token) {
              $window.alert(token);
              loginWindow.close();
              localStorageService.set('beats-token', token);
              $state.transitionTo('app.feed');
            } else {
            }
          }
        });
      });

    },

I managed to use Passport authentication with the InAppBrowser. Do you have more information on why cookies and sessions used by Passport is not suitable for a mobile app?

You provided the code to get the access token but then how do you pass it to the server, and most importantly how do you process it on the server. Basically how can I match the access token with a specific user?

Using passport, more specifically a session store, is a fine solution when using a mobile app. But there are less complex, I would say, easier solutions than so. Right now, your server is keeping track of current users with a session store. I prefer a pure stateless sever only serving JSON. You’ll associate the access token with the user the same way you’re doing now.

When you get the access token from passport, you either look up to see if that user exists, or you create a new one. If you’re using HTTPS you can just send the info to your server and make a new user. IF you’re not using HTTPS, you can just just hash the access token and send it along to your server along with the user’s other info and create a new user. Then using something like JWT, whenever your app wants to access your api, they must send that JWT with every request, probably an API token as well to prevent any App from accessing your API.

SO to be clear, your method is fine. I just find it easier to have the client send over a token to access endpoints (using HTTP interceptors) vs a session store.

3 Likes

Thanks for the clarification.

Could I get more info on the org.apache.cordova.inappbrowser implementation of passport.js? I just finished integrating my app with Satellizer. I can handle login w/ email just fine (or course no redirects there), but the authorization process craps out after I login to Facebook. I get this page:

Any thoughts?