Skip to main content

Authentication

Auth Server

Why do we need an Auth Server ?

To authenticate on Axioroute API, you need to pass username and password (or a refresh token), but also need to pass client_id and client_secret.

You should not expose client_id and client_secret in a web client app because they are sensitive credentials relative to your app (and not to the user). If these credentials are exposed, an attacker could use them to impersonate your application.

Instead, you should use a server-side component to handle authentication and authorization. The server-side component can securely store the client_id and client_secret and use them to obtain access tokens on behalf of the user. The access tokens can then be passed to the client-side app, which can use them to access protected resources.

By using this server-side component, you can ensure that sensitive credentials are not exposed to the client-side app and that access to protected resources is properly controlled.

Setup a local Auth Server

Here is a sample implementation of an Auth Server, that will be fine to use with your local development team but that could need some tuning to be used in production

Install dependencies

#we use pnpm but you can also use npm or yarn
pnpm add express dotenv body-parser axios cors ws

Add the Env file

.env
PORT=5175
CLIENT_ID="<YOUR_CLIENT_ID>"
CLIENT_SECRET="<YOUR_CLIENT_SECRET>"
API_KEY="<YOUR_API_KEY>"
API_AXIOROUTE_ENV="preprod"
AXIOROUTE_AUTH_URL='https://api.axioroute.com/auth/realms/axioroute/protocol/openid-connect/token'

Setup our auth server app

server.js
const express = require("express");
const cors = require("cors");
const dotenv = require("dotenv");
const http = require("http");
const axios = require("axios");

dotenv.config();

const app = express();
const httpServer = http.createServer(app);
const port = process.env.PORT;

const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());

app.get("/", (req, res) => {
res.send("Axioroute Minimal Auth Server with Express");
});

app.post("/auth", async (req, res) => {
try {
const { username, password, refresh_token } = req.body;

const data =
username && password
? {
grant_type: "password",
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
username,
password,
}
: {
grant_type: "refresh_token",
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
refresh_token,
};

const response = await axios({
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-AXIOROUTE-ENV": process.env.API_AXIOROUTE_ENV,
},
data,
url: process.env.AXIOROUTE_AUTH_URL,
});

res.header("Access-Control-Allow-Origin", ["*"]);

res.send(JSON.stringify(response.data));
} catch (e) {
res.send(
JSON.stringify({
e,
})
);
}
});

httpServer.listen(port, () => {
console.log(`listening on *:${port}`);
});
Note

Request to /auth endpoint will be used for both auth and refresh tokens.
Hence, you need to pass ether username + password OR refresh_token from the request body to the Axioroute Auth URL.

Start the Auth Server

node server.js

Your can now authenticate yourself on your client app by calling

import { ARRequestClient } from "@axioroute-sinari/axioroute-sdk";
ARRequestClient.setAuthUrl(`http://localhost:5175`);
await ARRequestClient.instance().auth("<USERNAME>", "<PASSWORD>");

Token Storage

Upon authentication, tokens are stored within browser localstorage.

Token Refresh

Token are automatically refreshed while active on the application (ie: before any API Call).

You can also explicitly ask for refresh with:

const myNewTokenData = await ARRequestClient.instance().refreshToken();