Over a million developers have joined DZone.

Combining Client-side Social Login and Server-side Authorization With Cordova and Node.js

It isn’t too difficult to add a social login aspect to your Apache Cordova application.

· Mobile Zone

Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud, brought to you in partnership with IBM.

I believe this wins the title for the longest blog title ever. So what in the hell am I talking about? It isn’t too difficult to add a social login aspect to your Apache Cordova application. I’ve used a variety of plugins/libraries in the past and for the most part – it just plain works. Recently however I ran into an issue that I didn’t know how to get around. Given that your mobile client authenticates a user against some OAuth provider, and given than you thenallow that user to interact with your server, how do a) ensure that the person running the server API is authenticated and b) how do you uniquely identify that user? That’s a bit abstract, so how about a real example?

Imagine you are building a mobile app that lets a user write notes. While you could store the notes on the client, you really need to store them in your own back end storage. In order to ensure that only authenticated users access your server APIs, you could build your own user system, have the user login (over https of course), store a session variable with their account info, and when they create data (or attempt to read data), use a primary key of some sort to get the right data.

That’s fairly boilerplate. But what happens when you mix in social login on the client-side? In that case, the mobile app handles the OAuth request to the provider and the provider returns a token. So on the client-side you know the current user is kosher. But when she makes a request to your Node (or ColdFusion, PHP, etc) server, how do you handle knowing the user was logged in – and even better – how do you get a unique identifier for that user so you can properly handle their data operations.

I did a bit of searching and came across this Stackoverflow post/answer: iOS & node.js: how to verify passed access token?. User Gijs responded that different OAuth providers have different ways of authenticating an access token. So the idea would be to pass the token to your back-end server, verify it, and then get a unique id.

I decided to give this a shot and build a simple proof of concept. This is very rough, but gives you a basic idea of how you could do this. For my POC, I decided to use Christophe Coenraet’s OpenFB library. It is a plugin-less JavaScript library that handles OAuth. Most recently I used ng-cordova-oauth as well, but I wanted to try something different. I created a quick Ionic application with two simple buttons:

Image title

The first button fires off the OAuth process. I followed Christophe’s directions and created my Facebook app first of course:

Image title

The code behind this is pretty simple:

$scope.doLogin = function() {
      function(response) {
        if(response.status === 'connected') {
          $scope.token = response.authResponse.accessToken;
          console.log('Token stored: ',response);
          alert('Ok, try to make a call now');
        } else {
          alert('Facebook login failed: ' + response.error);
      }, {scope: 'email'});                

Note I store the access token so I can use it later. Next – we need to call the server. If I remember right, Angular provides a way to modify all HTTP requests to include stuff. For now, I’m keeping it simple and just including the token as part of a form post.

$scope.doNode = function() {
    success(function() {
      console.log('yes im ok');
    error(function(data,status,headers,config) {
      console.log('error from node');

Ok, so far so good. Now let’s turn to the Node side. As mentioned in the StackOverflow post I linked to above, you can make a request to graph.facebook.com with the token and if you get the proper response, you know you’re good to go. I wrote a function I could use for middleware later on. It caches the test in the session scope which seems safe, but maybe that isn’t a good idea.

Something to note here: I’m specifically asking for the email address back. My result looks like this:

{ email: 'raymondcamden@gmail.com', id: 'abigassnumber' }

In theory, the ID is unique enough. However, if I use multiple different oauth providers, I can instead use the email as a primary key. That would let you login via Facebook or Twitter and have the same data as long as you have the same email address being used for both accounts. Note that I do not actually store that email address. I would in a real app. Finally, here is the route I called from the mobile app:

app.post('/test1', secure, function(req, res) {
console.log('attempting test1');
var msg = req.body.msg;
console.log('msg was '+msg);

It is pointless, but at least demonstrates using the secure function to wrap the route.

As I said – this is rough – but it seems to make sense to me. How about you?

The Mobile Zone is brought to you in partnership with Strongloop and IBM.  Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud.


Published at DZone with permission of Raymond Camden, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}