Custom Authentication

Ionic Cloud has been deprecated. To continue using Ionic services, migrate to Ionic Pro before Jan. 31, 2018.

Summary

Custom Authentication allows you make use of an existing authentication or user system with our User and Authentication services. With custom authentication you can integrate with systems such as:

Prerequisites

Setup

The first thing you’ll need to do is provide the following:

Navigate to Settings › User Auth in the Dashboard and configure your Custom provider details.

Security First! Although not strictly required, it is highly recommend to use an https:// endpoint for your production app.

Server Implementation

Regardless of your actual authentication process, a request is made to the endpoint you’ve specified. Here’s the breakdown of what needs to happen:

  1. Verify the incoming request is valid
  2. Perform your custom authentication process
  3. Redirect back to our servers with your unique user ID and associated user data

We’ve implemented several examples in various web frameworks and languages to help you get started:

Handling the Incoming Request

When a user attempts to login, we will redirect the user to your authentication endpoint with these query parameters.

https://example.com/authenticate?redirect_uri=1&state=2&token=3
redirect_uri This is the URL your server will redirect back to after a successful authentication.
state A nonce that prevents multiple authentication requests.
token The JWT with a payload containing app_id, exp, and optionally data.

Step 1: Verify the token

Verify the token sent with the request is able to be decoded using the shared secret you provided earlier. If you are unable to verify the token, you should issue a 401 HTTP response and continue no further as this may be a fraudulent request.

We use the HS256 algorithm to sign and verify JWTs. This is typically the default in most JWT libraries.

try {
  var incomingToken = jwt.verify(req.query.token, mySharedSecret);
} catch (ex) {
  console.error(ex.stack);
  return res.status(401).send('jwt error');
}

Step 2: Authenticate the user

This is where you’ll need to perform your own authentication using any data you’ve sent via your application or possibly displaying your own login form, etc.

Step 3: Redirecting

Once you’ve successfully authenticated the user, you’ll need to construct a JWT with a payload containing user_id, which must be a string value. Then redirect to redirect_uri with token (the generated outgoing JWT you just constructed) and state (the parameter which we use to verify your redirect) in the query string of the redirect URL.

We include query parameters in the redirect_uri. When appending additional query parameters to the redirect URL, there’s no need to prefix them with the ? delimiter.

var outgoingToken = jwt.sign({"user_id": user_id}, mySharedSecret);
var url = redirectUri +
  '&token=' + encodeURIComponent(outgoingToken) +
  '&state=' + encodeURIComponent(state);
  // If you want to test your implementation without the use of the Cloud Client, uncomment the following line.
  // '&redirect_uri=' + 'https://api.ionic.io/auth/integrations/custom/success';

return res.redirect(url);

After you redirect back to us, the authenticated user will exist in our system. We will generate a user ID for them and set their external_id to the user_id you gave us.

User Data

You can set user data during login. Alongside user_id in your outgoing token, send a custom object. When we merge data into the user, existing data is overwritten for each field.

var outgoingTokenPayload = {
  "user_id": "1234",
  "custom": {
    "marital_status": "single",
    "language": "en"
  }
};

var outgoingToken = jwt.sign(outgoingTokenPayload, mySharedSecret);

App Implementation

Once you’ve setup your server-side implementation, you can now move on to actually logging the user in.

Setup

Plugin Installation

The InAppBrowser plugin is used to login your users with custom authentication.

$ cordova plugin add cordova-plugin-inappbrowser --save

Injecting Auth and User

Import Auth and User from the Cloud Client and specify them as dependencies in your component constructor.

  • auth is a service that deals with registration and logging in/out.
  • user is a reference to the current user, whether that user is anonymous or authenticated.
import { Component } from '@angular/core';
import { Auth, User } from '@ionic/cloud-angular';

@Component( ... )
export class LoginPage {
  constructor(public auth: Auth, public user: User) {
    ...
  }
}

Specify ionic.cloud as a dependency for your module. This gives you access to $ionicAuth and $ionicUser.

  • $ionicAuth is a service that deals with registration and logging in/out.
  • $ionicUser is a reference to the current user, whether that user is anonymous or authenticated.
angular.module('myapp.controllers', ['ionic.cloud'])

.controller('MyCtrl', function($scope, $ionicAuth, $ionicUser) {
  ...
})

Login

If you want to authenticate users with a form on your website, the app code is pretty simple:

this.auth.login('custom').then( ... );
$ionicAuth.login('custom').then( ... );

If you prefer a login form in your app, you can login the user when the form is submitted, collecting whatever data you need. With this method, it makes sense to open the InAppBrowser window in the background. See all options for open.

let loginData = {'id': form.userId, 'passphrase': form.passphrase};
let loginOptions: AuthLoginOptions = {'inAppBrowserOptions': {'hidden': true}};

this.auth.login('custom', loginData, loginOptions).then( ... );
var loginData = {'id': form.userId, 'passphrase': form.passphrase};
var loginOptions = {'inAppBrowserOptions': {'hidden': true}};

$ionicAuth.login('custom', loginData, loginOptions).then( ... );

Logout

Logging out clears the current user context.

this.auth.logout();
$ionicAuth.logout();

Services

    API

      General