I have an authentication token I'd like to use in multiple Loopback 4 controllers. This token expires. Once expired I run some login logic to fetch a new token.
My issue is I'm not sure how or where to store this token.
So I can use this throughout my application I'm thinking to either save the token as a environment variable eg.
process.env.AUTH_TOKEN = 'TEST';
or use Loopback 4's Application-level context https://loopback.io/doc/en/lb4/Context.html
Are these suitable solutions for storing this token? If not what would be an alternative solution?
In the case of using Context, how would I go about doing this using best practices?
Taking all the comments above into account I would recommend you to crate a separate module which will encapsulate the logic related to your authentication token and how you use it. I.e. a new module will be responsible for:
I imagine your module in JavaScript may look something like:
let AUTH_TOKEN = "";
function makeAPICall(some, params) {
if (! AUTH_TOKEN) {
acquireNewToken();
}
if (expired()) {
refreshToken();
}
return "some_data"; // TODO: here you do you what you want with your auth token and return some data
}
function acquireNewToken() {
authToken = "new_token"; // TODO: put the logic to acquire a new token here
}
function refreshToken() {
authToken = "new_token"; // TODO: put the logic to refresh a token here
}
function expired() {
return false; // TODO: put the logic to check if token expired here
}
module.exports = {
makeAPICall: makeAPICall
};
Then you can require
the authModule
in all your controllers and use it like below:
let authModule = require('./modules/authModule');
authModule.makeAPICall("some", "params");
I believe you will never need to expose the auth token to your controllers as you can implement all the logic related to auth token usage within the authModule
and only pass some parameters to makeAPICall
function to tell it what to do and which data to get. But in case if you really need to expose it you can change the authModule
a bit (add getToken
function and add it to module.exports
):
function getToken() {
return authToken;
}
module.exports = {
makeAPICall: makeAPICall,
getToken: getToken
};
Now, let's get back to your questions:
Are these suitable solutions for storing this token? If not what would be an alternative solution?
As proposed above the solution is to store the token as a local variable in scope of custom module. Note, as Node.js uses caching for modules your AUTH_TOKEN
variable will be the same across all the controllers (every new require
will return you exactly the same object with the same token).
If you do not want to require
the authModule
every time you need to access your AUTH_TOKEN
you can also simply declare it as a global variable: global.AUTH_TOKEN = "";
. Note, that global variables have it's drawback like it may cause implicit coupling between files, etc. Here is a good article about when you should and when you should not use global variables: https://stackabuse.com/using-global-variables-in-node-js/
In the case of using Context, how would I go about doing this using best practices?
You can use Loopback 4 Context as well and it will be almost an equivalent of the solution with the custom authModule
I proposed above. The only difference with the customer module - you can put a bit more custom logic there and avoid copy-pasting some of your code in the controllers. With Loopback 4 Context you can use Server level context and store your AUTH_TOKEN
there, but you will still need some place where you get a new token and refresh it when it expires. Again, you can implement this logic in the custom authModule
. I.e. you can still keep that custom module and store the AUTH_TOKEN
in Loopback Context at the same time. This will be absolutely OK, but it will make the code a bit more complex from my point of view.