Skip to content

XSECURE setup

Azizul Hakim edited this page Apr 2, 2024 · 1 revision

IMS introduces an additional layer of security, enhancing the API's reliability and resilience. With this system, only applications possessing a shared XSECURITY_TOKEN can send API requests to the server; others will be blocked. To get started, follow the guide below.

Getting Started

By default, XSecure is disabled! To enable it, set the XSECURITY_ENABLED value to true in your .env file:

XSECURITY_ENABLED=true

Other wise it will be disabled.

Installation

Execute the following command to set up XSECURE:

php artisan xsecure:install

This command generates a secret for your application and updates your .env file with the XSECURITY_SECRET field.

After running the command, you will receive output similar to this:

Generated secret: zSaFVDakUcuT4+FVSom6RZTnCu7o/15PbtEBLwLNZxY=
XSECURITY_SECRET key have been updated in the .env file.

Use this secret in your frontend or mobile app to generate a short-lived XSecure token, which will be verified by the backend server.

Token Generation

Use the following examples to generate an XSecure token:

Typescript/Javascript Example

import crypto from "crypto";

export const generateXsecureToken = (secretKey: string): string => {
    // Calculate expiry timestamp (1 minute from current time)
    const expiryTimestamp = Math.floor(Date.now() / 1000) + 60;

    // Create payload object with expiry timestamp
    const payload = { expiry: expiryTimestamp };

    // Encode payload to Base64
    const token = Buffer.from(JSON.stringify(payload)).toString("base64");

    // Create HMAC signature using SHA-256 hash function
    const hmac = crypto.createHmac("sha256", secretKey);

    hmac.update(token);
    const signature = hmac.digest("hex");

    // Combine token and signature separated by a period
    return `${token}.${signature}`;
};

Flutter/Dart Example

import 'dart:convert';
import 'package:crypto/crypto.dart';

String generateXsecureToken(String secretKey) {
  // Calculate expiry timestamp (1 minute from current time)
  int expiryTimestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000 + 60;

  // Create payload map with expiry timestamp
  Map<String, dynamic> payload = {'expiry': expiryTimestamp};

  // Encode payload to Base64
  String token = base64Url.encode(utf8.encode(jsonEncode(payload)));

  // Create HMAC signature using SHA-256 hash function
  Hmac hmac = Hmac(sha256, utf8.encode(secretKey));
  String signature = hmac.convert(utf8.encode(token)).toString();

  // Combine token and signature separated by a period
  return '$token.$signature';
}

Example Token

The generated token will resemble the following:

eyJleHBpcnkiOjE3MTE5MDE2NjJ9.89b9c45cffee0072ea160441e2462a7ae2de8b484f5d1f5bf4e57f90b1340e0c

Ensure you include this token in the X-SECURITY-TOKEN header when sending requests to the backend server for verification:

 X-SECURITY-TOKEN: eyJleHBpcnkiOjE3MTE5MDE2NjJ9.89b9c45cffee0072ea160441e2462a7ae2de8b484f5d1f5bf4e57f90b1340e0c

This header will authenticate and authorize your requests, ensuring secure communication with the backend server.

Handling Invalid Tokens

If you send an invalid token, you will receive a JSON response like this:

{
   "error": "Invalid XSECURE token"
}