Custom-Auth Backend for Ionic.Auth using CakePHP

Ever since Ionic.Auth came out I wanted to create a custom-authorization using my CakePHP 2.6.x backend. The information that the Ionic team gave were really rare so I decided to dig a bit deeper into it.

Activate Custom Authorization in Ionic
First go to the Ionic Dashboard, activate custom-authorization, add a shared secret (this can be any string that you like) and add the URL to your custom-auth server:

Custom-auth in Ionic Dashboard
Custom-auth in Ionic Dashboard

So first let’s get all the parameters that are transmitted by Ionic:

$redirectUri = $this->request->query['redirect_uri'];
$state = $this->request->query['state'];
$token = $this->request->query['token'];

Now define the shared secred. Make sure that this matches the shared secret that you defined in the Ionic dashboard!

$sharedSecret = "some-random-string-that-you-like";

Let’s decode the token that was sent to us by Ionic. I am using the JWT class from Firebase. The Ionic team is using the HS256 algorithm, so we should also define it. You can get the JWT class from Firebase from here.

$decoded = JWT::decode($token, $sharedSecret, array('HS256'));

I tried a long time to finally get the structure of the data that was sent by Ionic. Here is a decoded sample:

"decoded": {
	"data": {
	  "password": "somePassword",
	  "email": "some@email.com"
	},
	"exp": 1457731231,
	"app_id": "8xb3x42"
}

Please note that the $decoded variable is not an array, it is an object. So you have to get your data like this:

$decoded->data->email

Now let’s do the authentication. First of all I am getting the current password hash from the user:

$usertmp = $this->User->find('first',
	array(
		'conditions' => array(
			'User.email' => $decoded->data->email
		),
		'fields' => array(
			'password'
		)
	)
);

Once I have the hash I can create a new hash for the password that was provided. Please note that I am using Blowfish!

$newHash = Security::hash($decoded->data->password, 'blowfish', $usertmp['User']['password']);

Now I try to get the user from the database with the given email address and password:

$user = $this->User->find('first', array(
	'conditions' => array(
		'User.email' => $decoded->data->email,
		'User.password' => $newHash,
		'User.is_active' => 1
	),
	'fields' => array(
		'id',
		'prename',
		'lastname',
		'is_active',
		'session_id',
		'username',
		'avatar',
		'photo_dir',
		'email'
	)
));

Now I check if the user exists. If the user does not exist, we have to throw a 401 exception (UnauthorizedException). If there the user successfully authenticated, we have to create a new variable and save the user_id from our backend. This payload has to be encoded again using our shared secred. Once this is done, we have to send our response back to Ionic:

if(empty($user)) {
	// return 401 auth error
	throw new UnauthorizedException(__('auth error'));
} else {
	$payload = array(
		'user_id' => $user['User']['id']
	);

	// encode payload
	$outgoingToken = JWT::encode($payload, $sharedSecret);

	// redirect back to ionic
	$url = $redirectUri . '&token=' . $outgoingToken . '&state=' . $state . '&redirect_uri=https://api.ionic.io/auth/integrations/custom/success';
	$this->redirect($url);
}

Update (24.03.2016): In case you want to get rid of the “You have successfully implemented custom authentication” screen, just change the url to this:

$url = $redirectUri . '&token=' . $outgoingToken . '&state=' . $state;

That’s it. If everything went well you should see a message that says “You have successfully implemented custom authentication” :) Let me know in the comments if that post was helpful!

You can find the whole function on Github.

5 Comments
  1. Reply Khaled Shaaban 5. April 2016 at 22:02

    I found this extremely helpful as ionic.io docs where somewhat vague to me regarding custom Auth. I use CakePHP 3.2 and got working using `$this->Auth->identify()` after assigning `$this->request->data` to hold the `$decoded->data`

  2. Reply Jonathan 13. September 2016 at 6:50

    Did you ever solved what happens on the client when auth returns 401?

    In my case the inApp browser just stays open when auth fails

  3. Reply Wawan Abnan 23. October 2016 at 19:22

    I m still do not get the true concept. What is end point url? is it our ionic app? will you create complete walk trough?

    thank

  4. Reply chrystopher salvador medina rebollar 10. December 2016 at 22:09

    hiiii, how can i sent custom data like username, email etc and in ionic access to that data

  5. Reply Paul 11. April 2017 at 13:16

    I’m also experiencing the same problem as Jonathan.
    If the login is not successful, the according callback does not seem to get fired.

Leave a Reply