Webdeveloper from the Netherlands, mostly focused on PHP. Co-founder and lead developer @ Fruitcake.nl

Sep 19, 2015

OAuth in Javascript Apps with Angular and Lumen, using Satellizer and Laravel Socialite

In the last few weeks, Socialite was a popular topic to blog/tweet about. Coincidentally, I also needed Socialite for a project. But in my case, I wanted to use it in an Angular app, distributed using Cordova (Phonegap) as hybrid app on Android/iOS. There were some examples, but I couldn’t find much about it at the time. A few people asked to share my experience about it, so here it is!

Before we start

As I said, a lot has been written about Socialite. So I’m going to assume you have Socialite working with Laravel or Lumen already. If you don’t, just read these links:

And off course some basis Angular knowledge would come in handy when you’re building an Angular app. So we’re also not covering installing Satellizer, but you can grab the example from the Github repo here.

So what are we going to use exactly?

Lumen a.k.a. Laravel Light, because we’re just building an API and want more speed. (But everything in this blog applies for Laravel also).

It sounds a bit complex (well, at least that was what I thought the first time I read it..), but let’s translate it for our use-case.

Call $auth.authenticate(‘google’).then(successCallback) in your Angular app and the popup opens.

The end-user logs in using his Social account.

The Social provider redirects to the URL you choose. The url should be the same as the domain your are on, otherwise you can’t access the code parameter. So for Cordova apps, http://localhost:3000 is fine. For apps on a ‘real’ domain, you can just use that. Just make sure it’s an allowed url. So you don’t use the Laravel API url as redirectUri!

Satellizer reads the code.

A POST request with the Authorization code is sent to the Lumen API.

Socialite exchanges the code for an access token.

Socialite uses this token to get the profile data.

Lumen either creates a new User or looks up the existing one (using the unique id of the profile)

A JSON Web Token is returned to Satellizer.

Satellizer stores the token for later use.

This is actually much easier than it looks, because Satellizer and Socialite do all the heavy lifting.

Handling the OAuth calls in Lumen

So how do we use Socialite to get the profile? Satellizer already has an example using Laravel but it doesn’t use Socialite, so it’s different for each provider. For example, Github:

So yeah, not very pretty when we have many providers. But we can see what it does:

Step 1: Exchange the received Authorization code for an Access token

Step 2: Use token to get the Social profile.

Step 3a: When already logged in, connect this network to the logged in user.

Step 3b: Otherwise look up the user with this profile id, or create a new one.

Return a token for Satellizer.

How can we do this with Socialite? The first 2 steps can be done by Socialite directly. We just need to set the correct redirectUri, as provided by the Request from Satellizer. We also setting it to be stateless, because we’re not using the Session for the API.

So we’re kind of faking the Session, because A) we’re not using the session and B) We can’t use the session because Satellizer makes the actual request. This could probably be improved somehow, but would require some changes in Satellizer.

Satellizer can parse the token to find out if it’s still valid (you can’t invalidate it, it just expires). Unfortunately there isn’t an option to refresh a token yet in Satellizer, but you could probably build it yourself. Otherwise the users just gets logged out after a year.

Satellizer sends the token in the Authorization header, so we can verify this. We’ll create an middleware for this. We’re doing it a bit different than the example (again):

So we’re logging this user in for just his one request (we’re not using a session, remember). That means we can use Auth::check() and Auth::user() in our code. No need for different JWT/Auth libraries, just our checks as usual. You can still combine this middleware with the normal auth middleware.

So this is pretty much all that’s needed to get your Angular app to play nice with Lumen (or Laravel, which is pretty much exactly the same). If you have any improvements or tips, feel free to open an issue/pull request on barryvdh/barryvdh.github.io

Some gotcha’s

You need to add some lines to you .htaccess to actually get the Authorization Header in your Laravel code: