Asynchronously authenticate before request
So I have an API and I am trying to authenticate by hitting an endpoint with credentials (this part I've gotten working) and then save the received token and use it in all subsequent requests.
My problem is that the authenticate()
method is asynchronous, but all other request methods like get()
need the token from the authenticate()
method. So I can't just export my get()
method because the export is synchronous (as I've read) and it will be exported before authentication happens. I could authenticate for every request but that seems wasteful and inefficient.
I am not sure what to do here, I'm using axios, what's the proper way of doing this?
Edit
I'll be a bit more specific here. I have created an axios instance:
var instance = axios.create(
baseURL: `http://$config.server:$config.port`,
timeout: 1000,
headers:
'Content-Type': 'application/json',
'Accept': 'application/json'
)
I want to get the authentication token, and include it in the instance header:
async function authenticate(instance)
const result = await instance.post(
'/session',
'username': config.username,
'password': config.password
)
instance['X-Token'] = result.data.token
Now I want to export that instance to be used in other files
javascript asynchronous axios
add a comment |
So I have an API and I am trying to authenticate by hitting an endpoint with credentials (this part I've gotten working) and then save the received token and use it in all subsequent requests.
My problem is that the authenticate()
method is asynchronous, but all other request methods like get()
need the token from the authenticate()
method. So I can't just export my get()
method because the export is synchronous (as I've read) and it will be exported before authentication happens. I could authenticate for every request but that seems wasteful and inefficient.
I am not sure what to do here, I'm using axios, what's the proper way of doing this?
Edit
I'll be a bit more specific here. I have created an axios instance:
var instance = axios.create(
baseURL: `http://$config.server:$config.port`,
timeout: 1000,
headers:
'Content-Type': 'application/json',
'Accept': 'application/json'
)
I want to get the authentication token, and include it in the instance header:
async function authenticate(instance)
const result = await instance.post(
'/session',
'username': config.username,
'password': config.password
)
instance['X-Token'] = result.data.token
Now I want to export that instance to be used in other files
javascript asynchronous axios
you can await it if you have ES6. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– ruby_newbie
Nov 14 '18 at 22:13
Can you show me an example? Pseudocode is fine
– Dan M
Nov 14 '18 at 22:14
Sure.const token = await authenticate() const res = get(endpoint, token);
– ruby_newbie
Nov 14 '18 at 22:16
1
@ruby_newbieawait
was introduced in ECMAScript 2017, not in ECMAScript 2015 (aka ES6)
– Patrick Roberts
Nov 14 '18 at 22:24
add a comment |
So I have an API and I am trying to authenticate by hitting an endpoint with credentials (this part I've gotten working) and then save the received token and use it in all subsequent requests.
My problem is that the authenticate()
method is asynchronous, but all other request methods like get()
need the token from the authenticate()
method. So I can't just export my get()
method because the export is synchronous (as I've read) and it will be exported before authentication happens. I could authenticate for every request but that seems wasteful and inefficient.
I am not sure what to do here, I'm using axios, what's the proper way of doing this?
Edit
I'll be a bit more specific here. I have created an axios instance:
var instance = axios.create(
baseURL: `http://$config.server:$config.port`,
timeout: 1000,
headers:
'Content-Type': 'application/json',
'Accept': 'application/json'
)
I want to get the authentication token, and include it in the instance header:
async function authenticate(instance)
const result = await instance.post(
'/session',
'username': config.username,
'password': config.password
)
instance['X-Token'] = result.data.token
Now I want to export that instance to be used in other files
javascript asynchronous axios
So I have an API and I am trying to authenticate by hitting an endpoint with credentials (this part I've gotten working) and then save the received token and use it in all subsequent requests.
My problem is that the authenticate()
method is asynchronous, but all other request methods like get()
need the token from the authenticate()
method. So I can't just export my get()
method because the export is synchronous (as I've read) and it will be exported before authentication happens. I could authenticate for every request but that seems wasteful and inefficient.
I am not sure what to do here, I'm using axios, what's the proper way of doing this?
Edit
I'll be a bit more specific here. I have created an axios instance:
var instance = axios.create(
baseURL: `http://$config.server:$config.port`,
timeout: 1000,
headers:
'Content-Type': 'application/json',
'Accept': 'application/json'
)
I want to get the authentication token, and include it in the instance header:
async function authenticate(instance)
const result = await instance.post(
'/session',
'username': config.username,
'password': config.password
)
instance['X-Token'] = result.data.token
Now I want to export that instance to be used in other files
javascript asynchronous axios
javascript asynchronous axios
edited Nov 14 '18 at 22:22
Dan M
asked Nov 14 '18 at 22:12
Dan MDan M
112
112
you can await it if you have ES6. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– ruby_newbie
Nov 14 '18 at 22:13
Can you show me an example? Pseudocode is fine
– Dan M
Nov 14 '18 at 22:14
Sure.const token = await authenticate() const res = get(endpoint, token);
– ruby_newbie
Nov 14 '18 at 22:16
1
@ruby_newbieawait
was introduced in ECMAScript 2017, not in ECMAScript 2015 (aka ES6)
– Patrick Roberts
Nov 14 '18 at 22:24
add a comment |
you can await it if you have ES6. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– ruby_newbie
Nov 14 '18 at 22:13
Can you show me an example? Pseudocode is fine
– Dan M
Nov 14 '18 at 22:14
Sure.const token = await authenticate() const res = get(endpoint, token);
– ruby_newbie
Nov 14 '18 at 22:16
1
@ruby_newbieawait
was introduced in ECMAScript 2017, not in ECMAScript 2015 (aka ES6)
– Patrick Roberts
Nov 14 '18 at 22:24
you can await it if you have ES6. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– ruby_newbie
Nov 14 '18 at 22:13
you can await it if you have ES6. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– ruby_newbie
Nov 14 '18 at 22:13
Can you show me an example? Pseudocode is fine
– Dan M
Nov 14 '18 at 22:14
Can you show me an example? Pseudocode is fine
– Dan M
Nov 14 '18 at 22:14
Sure.
const token = await authenticate() const res = get(endpoint, token);
– ruby_newbie
Nov 14 '18 at 22:16
Sure.
const token = await authenticate() const res = get(endpoint, token);
– ruby_newbie
Nov 14 '18 at 22:16
1
1
@ruby_newbie
await
was introduced in ECMAScript 2017, not in ECMAScript 2015 (aka ES6)– Patrick Roberts
Nov 14 '18 at 22:24
@ruby_newbie
await
was introduced in ECMAScript 2017, not in ECMAScript 2015 (aka ES6)– Patrick Roberts
Nov 14 '18 at 22:24
add a comment |
2 Answers
2
active
oldest
votes
You can use async/await
. This is semi-pseudocode:
async function doStuff()
const result = await axios.authenticate();
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
Alternatively, you can just use then
:
function doStuff(token)
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
axios.authenticate().then(result =>
const token = // extract token from whatever format of result is
doStuff(token);
Ok, but this model is on a per request basis. I want to save the token, include it in the axios instance header, and then be able to make requests using that instance and not having to manually include the header every time
– Dan M
Nov 14 '18 at 22:19
1
One way to do this is to to use authenticate().then() chain on first request (or if token is not present), and skip it if token is present for subsequent requests.
– ODYN-Kon
Nov 14 '18 at 22:22
So for every API call I would need to have a built in conditional to check if the token is set before I make the request? Is there not a way to set the token once, assign it to an axios instance, and then import that instance into whatever files require it to make API calls?
– Dan M
Nov 15 '18 at 16:11
You can but you need to make sure that happens before your first call toget()
.
– ODYN-Kon
Nov 15 '18 at 16:16
Haha, yes! That is exactly what I want to do, I just don't know how!
– Dan M
Nov 15 '18 at 16:21
add a comment |
With Axios you have the ability to set default values for all requests.
So for just a single axios instance you can do...
async function authenticate(instance)
const result = await instance.post(
'/session',
'username': config.username,
'password': config.password
)
instance.defaults.headers.common['X-Token'] = result.data.token;
Alternatively, (which it sounds like you want to do) you can add it for the default Axios export. Then all requests will automatically have the header.
async function authenticate(endpoint, username, password)
const res = await axios.post(`$endpoint/session`, username, password );
axios.defaults.headers.common['X-Token'] = result.data.token;
Then you don't have to worry about passing around an instance between all parts of your app and can just use import * as axios from 'axios'
and have the header set.
Axios also provides and extremely helpful function called interceptors which you can use to inspect a request prior to making it. You can use to check to make sure that the request has the auth header and if it doesn't you can perform that logic. I came up with this and it seems to work well!
axios.interceptors.request.use(async (config) =>
// request intercepted, check (1) the header is missing and (2) that the intercepted request isn't authorizing
if (!config.headers.common['X-Token'] && config.authorizing !== true)
const endpoint, username, password = appConfig;
// make a request to get your token AND pass our custom config
const result = await axios.post(`$endpoint/session`, username, password , authorizing: true );
// update axios to include the header for future requests
axios.defaults.headers.common['X-Token'] = result.data.token;
return config;
);
Two things that you'll want to note -- not only do I check for the existence of your X-token header I also check for a new authorization value in the config. You want to check for that config value, because we are going to use it as a flag to let the interceptor know if it should skip a request. If you don't do this, the authorization request will trigger another authorization request and infinite loop.
Apologies for the somewhat late reply, and thank you for your response. I see how this is valuable, but I still don't see how I can run this authentication step synchronously so that I have the token set in the header before I make any other api calls. Maybe I am just being an idiot, but it would really help me out if you had some kind of example perhaps?
– Dan M
Nov 15 '18 at 16:04
Okay I get what you want to do, I updated my answer to provide that logic!
– kyle
Nov 15 '18 at 23:32
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53309514%2fasynchronously-authenticate-before-request%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can use async/await
. This is semi-pseudocode:
async function doStuff()
const result = await axios.authenticate();
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
Alternatively, you can just use then
:
function doStuff(token)
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
axios.authenticate().then(result =>
const token = // extract token from whatever format of result is
doStuff(token);
Ok, but this model is on a per request basis. I want to save the token, include it in the axios instance header, and then be able to make requests using that instance and not having to manually include the header every time
– Dan M
Nov 14 '18 at 22:19
1
One way to do this is to to use authenticate().then() chain on first request (or if token is not present), and skip it if token is present for subsequent requests.
– ODYN-Kon
Nov 14 '18 at 22:22
So for every API call I would need to have a built in conditional to check if the token is set before I make the request? Is there not a way to set the token once, assign it to an axios instance, and then import that instance into whatever files require it to make API calls?
– Dan M
Nov 15 '18 at 16:11
You can but you need to make sure that happens before your first call toget()
.
– ODYN-Kon
Nov 15 '18 at 16:16
Haha, yes! That is exactly what I want to do, I just don't know how!
– Dan M
Nov 15 '18 at 16:21
add a comment |
You can use async/await
. This is semi-pseudocode:
async function doStuff()
const result = await axios.authenticate();
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
Alternatively, you can just use then
:
function doStuff(token)
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
axios.authenticate().then(result =>
const token = // extract token from whatever format of result is
doStuff(token);
Ok, but this model is on a per request basis. I want to save the token, include it in the axios instance header, and then be able to make requests using that instance and not having to manually include the header every time
– Dan M
Nov 14 '18 at 22:19
1
One way to do this is to to use authenticate().then() chain on first request (or if token is not present), and skip it if token is present for subsequent requests.
– ODYN-Kon
Nov 14 '18 at 22:22
So for every API call I would need to have a built in conditional to check if the token is set before I make the request? Is there not a way to set the token once, assign it to an axios instance, and then import that instance into whatever files require it to make API calls?
– Dan M
Nov 15 '18 at 16:11
You can but you need to make sure that happens before your first call toget()
.
– ODYN-Kon
Nov 15 '18 at 16:16
Haha, yes! That is exactly what I want to do, I just don't know how!
– Dan M
Nov 15 '18 at 16:21
add a comment |
You can use async/await
. This is semi-pseudocode:
async function doStuff()
const result = await axios.authenticate();
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
Alternatively, you can just use then
:
function doStuff(token)
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
axios.authenticate().then(result =>
const token = // extract token from whatever format of result is
doStuff(token);
You can use async/await
. This is semi-pseudocode:
async function doStuff()
const result = await axios.authenticate();
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
Alternatively, you can just use then
:
function doStuff(token)
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
axios.authenticate().then(result =>
const token = // extract token from whatever format of result is
doStuff(token);
answered Nov 14 '18 at 22:16
ODYN-KonODYN-Kon
2,3322825
2,3322825
Ok, but this model is on a per request basis. I want to save the token, include it in the axios instance header, and then be able to make requests using that instance and not having to manually include the header every time
– Dan M
Nov 14 '18 at 22:19
1
One way to do this is to to use authenticate().then() chain on first request (or if token is not present), and skip it if token is present for subsequent requests.
– ODYN-Kon
Nov 14 '18 at 22:22
So for every API call I would need to have a built in conditional to check if the token is set before I make the request? Is there not a way to set the token once, assign it to an axios instance, and then import that instance into whatever files require it to make API calls?
– Dan M
Nov 15 '18 at 16:11
You can but you need to make sure that happens before your first call toget()
.
– ODYN-Kon
Nov 15 '18 at 16:16
Haha, yes! That is exactly what I want to do, I just don't know how!
– Dan M
Nov 15 '18 at 16:21
add a comment |
Ok, but this model is on a per request basis. I want to save the token, include it in the axios instance header, and then be able to make requests using that instance and not having to manually include the header every time
– Dan M
Nov 14 '18 at 22:19
1
One way to do this is to to use authenticate().then() chain on first request (or if token is not present), and skip it if token is present for subsequent requests.
– ODYN-Kon
Nov 14 '18 at 22:22
So for every API call I would need to have a built in conditional to check if the token is set before I make the request? Is there not a way to set the token once, assign it to an axios instance, and then import that instance into whatever files require it to make API calls?
– Dan M
Nov 15 '18 at 16:11
You can but you need to make sure that happens before your first call toget()
.
– ODYN-Kon
Nov 15 '18 at 16:16
Haha, yes! That is exactly what I want to do, I just don't know how!
– Dan M
Nov 15 '18 at 16:21
Ok, but this model is on a per request basis. I want to save the token, include it in the axios instance header, and then be able to make requests using that instance and not having to manually include the header every time
– Dan M
Nov 14 '18 at 22:19
Ok, but this model is on a per request basis. I want to save the token, include it in the axios instance header, and then be able to make requests using that instance and not having to manually include the header every time
– Dan M
Nov 14 '18 at 22:19
1
1
One way to do this is to to use authenticate().then() chain on first request (or if token is not present), and skip it if token is present for subsequent requests.
– ODYN-Kon
Nov 14 '18 at 22:22
One way to do this is to to use authenticate().then() chain on first request (or if token is not present), and skip it if token is present for subsequent requests.
– ODYN-Kon
Nov 14 '18 at 22:22
So for every API call I would need to have a built in conditional to check if the token is set before I make the request? Is there not a way to set the token once, assign it to an axios instance, and then import that instance into whatever files require it to make API calls?
– Dan M
Nov 15 '18 at 16:11
So for every API call I would need to have a built in conditional to check if the token is set before I make the request? Is there not a way to set the token once, assign it to an axios instance, and then import that instance into whatever files require it to make API calls?
– Dan M
Nov 15 '18 at 16:11
You can but you need to make sure that happens before your first call to
get()
.– ODYN-Kon
Nov 15 '18 at 16:16
You can but you need to make sure that happens before your first call to
get()
.– ODYN-Kon
Nov 15 '18 at 16:16
Haha, yes! That is exactly what I want to do, I just don't know how!
– Dan M
Nov 15 '18 at 16:21
Haha, yes! That is exactly what I want to do, I just don't know how!
– Dan M
Nov 15 '18 at 16:21
add a comment |
With Axios you have the ability to set default values for all requests.
So for just a single axios instance you can do...
async function authenticate(instance)
const result = await instance.post(
'/session',
'username': config.username,
'password': config.password
)
instance.defaults.headers.common['X-Token'] = result.data.token;
Alternatively, (which it sounds like you want to do) you can add it for the default Axios export. Then all requests will automatically have the header.
async function authenticate(endpoint, username, password)
const res = await axios.post(`$endpoint/session`, username, password );
axios.defaults.headers.common['X-Token'] = result.data.token;
Then you don't have to worry about passing around an instance between all parts of your app and can just use import * as axios from 'axios'
and have the header set.
Axios also provides and extremely helpful function called interceptors which you can use to inspect a request prior to making it. You can use to check to make sure that the request has the auth header and if it doesn't you can perform that logic. I came up with this and it seems to work well!
axios.interceptors.request.use(async (config) =>
// request intercepted, check (1) the header is missing and (2) that the intercepted request isn't authorizing
if (!config.headers.common['X-Token'] && config.authorizing !== true)
const endpoint, username, password = appConfig;
// make a request to get your token AND pass our custom config
const result = await axios.post(`$endpoint/session`, username, password , authorizing: true );
// update axios to include the header for future requests
axios.defaults.headers.common['X-Token'] = result.data.token;
return config;
);
Two things that you'll want to note -- not only do I check for the existence of your X-token header I also check for a new authorization value in the config. You want to check for that config value, because we are going to use it as a flag to let the interceptor know if it should skip a request. If you don't do this, the authorization request will trigger another authorization request and infinite loop.
Apologies for the somewhat late reply, and thank you for your response. I see how this is valuable, but I still don't see how I can run this authentication step synchronously so that I have the token set in the header before I make any other api calls. Maybe I am just being an idiot, but it would really help me out if you had some kind of example perhaps?
– Dan M
Nov 15 '18 at 16:04
Okay I get what you want to do, I updated my answer to provide that logic!
– kyle
Nov 15 '18 at 23:32
add a comment |
With Axios you have the ability to set default values for all requests.
So for just a single axios instance you can do...
async function authenticate(instance)
const result = await instance.post(
'/session',
'username': config.username,
'password': config.password
)
instance.defaults.headers.common['X-Token'] = result.data.token;
Alternatively, (which it sounds like you want to do) you can add it for the default Axios export. Then all requests will automatically have the header.
async function authenticate(endpoint, username, password)
const res = await axios.post(`$endpoint/session`, username, password );
axios.defaults.headers.common['X-Token'] = result.data.token;
Then you don't have to worry about passing around an instance between all parts of your app and can just use import * as axios from 'axios'
and have the header set.
Axios also provides and extremely helpful function called interceptors which you can use to inspect a request prior to making it. You can use to check to make sure that the request has the auth header and if it doesn't you can perform that logic. I came up with this and it seems to work well!
axios.interceptors.request.use(async (config) =>
// request intercepted, check (1) the header is missing and (2) that the intercepted request isn't authorizing
if (!config.headers.common['X-Token'] && config.authorizing !== true)
const endpoint, username, password = appConfig;
// make a request to get your token AND pass our custom config
const result = await axios.post(`$endpoint/session`, username, password , authorizing: true );
// update axios to include the header for future requests
axios.defaults.headers.common['X-Token'] = result.data.token;
return config;
);
Two things that you'll want to note -- not only do I check for the existence of your X-token header I also check for a new authorization value in the config. You want to check for that config value, because we are going to use it as a flag to let the interceptor know if it should skip a request. If you don't do this, the authorization request will trigger another authorization request and infinite loop.
Apologies for the somewhat late reply, and thank you for your response. I see how this is valuable, but I still don't see how I can run this authentication step synchronously so that I have the token set in the header before I make any other api calls. Maybe I am just being an idiot, but it would really help me out if you had some kind of example perhaps?
– Dan M
Nov 15 '18 at 16:04
Okay I get what you want to do, I updated my answer to provide that logic!
– kyle
Nov 15 '18 at 23:32
add a comment |
With Axios you have the ability to set default values for all requests.
So for just a single axios instance you can do...
async function authenticate(instance)
const result = await instance.post(
'/session',
'username': config.username,
'password': config.password
)
instance.defaults.headers.common['X-Token'] = result.data.token;
Alternatively, (which it sounds like you want to do) you can add it for the default Axios export. Then all requests will automatically have the header.
async function authenticate(endpoint, username, password)
const res = await axios.post(`$endpoint/session`, username, password );
axios.defaults.headers.common['X-Token'] = result.data.token;
Then you don't have to worry about passing around an instance between all parts of your app and can just use import * as axios from 'axios'
and have the header set.
Axios also provides and extremely helpful function called interceptors which you can use to inspect a request prior to making it. You can use to check to make sure that the request has the auth header and if it doesn't you can perform that logic. I came up with this and it seems to work well!
axios.interceptors.request.use(async (config) =>
// request intercepted, check (1) the header is missing and (2) that the intercepted request isn't authorizing
if (!config.headers.common['X-Token'] && config.authorizing !== true)
const endpoint, username, password = appConfig;
// make a request to get your token AND pass our custom config
const result = await axios.post(`$endpoint/session`, username, password , authorizing: true );
// update axios to include the header for future requests
axios.defaults.headers.common['X-Token'] = result.data.token;
return config;
);
Two things that you'll want to note -- not only do I check for the existence of your X-token header I also check for a new authorization value in the config. You want to check for that config value, because we are going to use it as a flag to let the interceptor know if it should skip a request. If you don't do this, the authorization request will trigger another authorization request and infinite loop.
With Axios you have the ability to set default values for all requests.
So for just a single axios instance you can do...
async function authenticate(instance)
const result = await instance.post(
'/session',
'username': config.username,
'password': config.password
)
instance.defaults.headers.common['X-Token'] = result.data.token;
Alternatively, (which it sounds like you want to do) you can add it for the default Axios export. Then all requests will automatically have the header.
async function authenticate(endpoint, username, password)
const res = await axios.post(`$endpoint/session`, username, password );
axios.defaults.headers.common['X-Token'] = result.data.token;
Then you don't have to worry about passing around an instance between all parts of your app and can just use import * as axios from 'axios'
and have the header set.
Axios also provides and extremely helpful function called interceptors which you can use to inspect a request prior to making it. You can use to check to make sure that the request has the auth header and if it doesn't you can perform that logic. I came up with this and it seems to work well!
axios.interceptors.request.use(async (config) =>
// request intercepted, check (1) the header is missing and (2) that the intercepted request isn't authorizing
if (!config.headers.common['X-Token'] && config.authorizing !== true)
const endpoint, username, password = appConfig;
// make a request to get your token AND pass our custom config
const result = await axios.post(`$endpoint/session`, username, password , authorizing: true );
// update axios to include the header for future requests
axios.defaults.headers.common['X-Token'] = result.data.token;
return config;
);
Two things that you'll want to note -- not only do I check for the existence of your X-token header I also check for a new authorization value in the config. You want to check for that config value, because we are going to use it as a flag to let the interceptor know if it should skip a request. If you don't do this, the authorization request will trigger another authorization request and infinite loop.
edited Nov 15 '18 at 23:32
answered Nov 14 '18 at 22:28
kylekyle
1,11031127
1,11031127
Apologies for the somewhat late reply, and thank you for your response. I see how this is valuable, but I still don't see how I can run this authentication step synchronously so that I have the token set in the header before I make any other api calls. Maybe I am just being an idiot, but it would really help me out if you had some kind of example perhaps?
– Dan M
Nov 15 '18 at 16:04
Okay I get what you want to do, I updated my answer to provide that logic!
– kyle
Nov 15 '18 at 23:32
add a comment |
Apologies for the somewhat late reply, and thank you for your response. I see how this is valuable, but I still don't see how I can run this authentication step synchronously so that I have the token set in the header before I make any other api calls. Maybe I am just being an idiot, but it would really help me out if you had some kind of example perhaps?
– Dan M
Nov 15 '18 at 16:04
Okay I get what you want to do, I updated my answer to provide that logic!
– kyle
Nov 15 '18 at 23:32
Apologies for the somewhat late reply, and thank you for your response. I see how this is valuable, but I still don't see how I can run this authentication step synchronously so that I have the token set in the header before I make any other api calls. Maybe I am just being an idiot, but it would really help me out if you had some kind of example perhaps?
– Dan M
Nov 15 '18 at 16:04
Apologies for the somewhat late reply, and thank you for your response. I see how this is valuable, but I still don't see how I can run this authentication step synchronously so that I have the token set in the header before I make any other api calls. Maybe I am just being an idiot, but it would really help me out if you had some kind of example perhaps?
– Dan M
Nov 15 '18 at 16:04
Okay I get what you want to do, I updated my answer to provide that logic!
– kyle
Nov 15 '18 at 23:32
Okay I get what you want to do, I updated my answer to provide that logic!
– kyle
Nov 15 '18 at 23:32
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53309514%2fasynchronously-authenticate-before-request%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
you can await it if you have ES6. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– ruby_newbie
Nov 14 '18 at 22:13
Can you show me an example? Pseudocode is fine
– Dan M
Nov 14 '18 at 22:14
Sure.
const token = await authenticate() const res = get(endpoint, token);
– ruby_newbie
Nov 14 '18 at 22:16
1
@ruby_newbie
await
was introduced in ECMAScript 2017, not in ECMAScript 2015 (aka ES6)– Patrick Roberts
Nov 14 '18 at 22:24