Quick Guide

Introduction

Below is a quick guide on how to integrate Instalogin in your project to test it easily. We are preparing a comprehensive documentation covering all possible use cases and parameters.

Notice: This documentation is work in progress.

Prerequisites

To use the Almefy API you’ll be provided a Key and a Secret, which will be used to authenticate at our API. The binary secret is Base64 encoded.

KEY=5bbf4923faf099a3515a40d9b0e6e6e32c890ef6cd7a8a120657c2f49d2341fe
SECRET=Fw59ctgPG8u4NbDJH7KiO8H1SySAGeDWvE9QrBDxygCPACKOP9DbN/yvHRWJAoYR45dqytYOx4APcAuZ3lSR/w==

Notice: Example Data

Authentication

We use signed Json Web Tokens (JWT) for API authentication. To provide maximum security, we also use additional claims related to the request.

The following example request:

POST /v1/entity/identities/enroll HTTP/1.1
Content-Type: application/json; charset=utf-8
...
{"identifier":"john.doe","sendEmail":true,"sendEmailTo":"john.doe@example.com"}

would require a JWT with a structure similar to this:

// JWT Header
{
  "typ": "JWT",
  "alg": "HS256"
}

// JWT Claims
{
  // API Key
  "iss": "5bbf4923faf099a3515a40d9b0e6e6e32c890ef6cd7a8a120657c2f49d2341fe",
  // API Host
  "aud": "https://api.almefy.com",
  // "Issued At" Current Unix Timestamp (seconds since Jan 01 1970)
  "iat": 1577833201,
  // "Not Before" Current Unix Timestamp (seconds since Jan 01 1970)
  "nbf": 1577833201,
  // "Expiration Time" Current Unix Timestamp (seconds since Jan 01 1970)
  "exp": 1577833211, // Add e.g. 10 seconds to address latency
  // Request method, in upper letters
  "method": "POST",
  // Full URL to the API endpoint
  "url": "https://api.almefy.com/v1/entity/identities/enroll", 
  // The bodyHash below is a SHA256 hash of the request body in the example request
  "bodyHash": "cffe073b895526943614212f20207aa982846918476fbde32dcb66e484b010ef"
}

Notice: These are the minimum claims required by the Almefy API.

This JWT needs then to be signed with the API secret provided by Almefy.

Please Notice

For many HMAC SHA256 functions the secret parameter needs to be provided as binary representation of the Base64 encrypted API secret.

Then simply add the signed JWT as an authorization header inside the request:

POST /v1/entity/identities/enroll HTTP/1.1
Content-Type: application/json; charset=utf-8
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOweqwe2241dgweiIw2324ew23qd ...
{"identifier":"john.doe","sendEmail":true,"sebdEmailTo":"john.doe@example.com"}


 

Enroll Identity

Before a user account can be used with the Almefy app, an Identity for that account needs to be enrolled and a device provisioned. The easiest way to start an enrollment is to send the user an Email with an enrollment QR Code inside. A good starting point could be a "Link with Almefy" button somewhere in the protected frontend or administration backend, which triggers the following API call in the backend (simplified view):

POST /v1/entity/identities/enroll HTTP/1.1
{
  "identifier": "john.doe"
}

Notice: Check out the API Enrollment Reference for all available options.

The response is enrollment data with a response status of either 201 (Created) or 200 (Ok, updated), and will look something like this:

{
  "id": "1d5e36b89c",
  "createdAt": "2020-02-25T08:26:50+00:00",
  "expiresAt": "2020-02-25T09:26:50+00:00",
  "base64ImageData": "BINARY_DATA",
  "identity": {
    "id": "0aa249e2-94ca-4bb2-89cf-bc3a329f4aac",
    "createdAt": "2020-02-21T10:16:11+00:00",
    "locked": false,
    "identifier": "john.doe",
    "nickname": null,
    "label": "john.doe",
    "role": "ROLE_USER",
    "tokens": []
  }
}

This API call, regardless how often it is being called, simply creates or updates an existing identity inside the Almefy system, and sends out an email with a provisioning QR Code that needs to be scanned with the Almefy app. Once done, the enrollment & provisioning is completed, and the user is ready to authenticate using the Almefy app.

Show Auth Image

Add the following few lines to your HTML frontend to show the Almefy auth image used for authentication.

<!-- Place this HTML code wherever the Almefy image should appear -->
<div data-almefy-auth
     data-almefy-key="5bbf4923faf099a3515a40d9b0e6e6e32c890ef6cd7a8a120657c2f49d2341fe"
     data-almefy-auth-url="/path/to/auth-controller"></div>

<!-- Load the JavaScript library -->
<script defer src="https://cdn.almefy.com/js/almefy-1.0.0.js"
        integrity="sha384-9cWXAg8MurIKKZOnt0x5QIm7o6HzOwVT9r03rLTSwkjti7f4SEmJAM1CZPBJkZ1X"
        crossorigin="anonymous"></script>

Notice: Please see the JavaScript SDK for list of available parameters

Process Auth Token

The controller configured in the data-almefy-auth-url attribute will receive a signed JWT inside the X-Almefy-Auth header. A request to this controller will look something like:

GET /path/to/auth-controller HTTP/1.1
Accept: application/json
X-Requested-With: XMLHttpRequest
X-Almefy-Auth: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOweqwe2241dgweiIw2324ew23qd ...



 

The first thing that needs to be done inside the controller is to extract the JWT from the header and validate it with any JWT utility class using the API secret. Once done, you can retrieve three important claims from the JWT:

{
  "jti": "c29a49e4b1", // Challenge Id
  "sub": "john.doe",   // Identifier
  "otp": "1c7eab97"    // One Time Password
}

The next step is to use your own internal logic to check, if the user with the identifier from the JWTs sub claim is actually in your database and enabled to authenticate into your application. As a final step you need to confirm the authentication on the Almefy system by validating the challenge and otp claim. This also ensures that the provided data is consumed and not available for further requests:

POST /v1/entity/identities/john.doe/authenticate HTTP/1.1
{
  "challenge": "c29a49e4b1",
  "otp": "1c7eab97"
}

Please notice, it is recommended to url-encode the “identifier” parameter when calling the authentication endpoint from the Almefy API:

POST /v1/entity/identities/{identifier}/authenticate HTTP/1.1
{
  ...
}

The response is either a status code of 200 (Ok) or 401 (Unauthorized). At this point the user is successfully authenticated, the session can be set up and user redirected. The embedded Almefy JavaScript handles any redirect response internally, you just have to return the appropriate redirect response (e.g. 301) with the final location from the controller.