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
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
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}`);
});
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();