Axios - Sending always default header - javascript

I have an app where most of the endpoints use the same token to authenticate. So, when a user logs in I use the following:
axios.defaults.headers.common['Authorization'] = 'Bearer ' + user.access_token
But I have some endpoints that have a different Bearer token. In these cases, I'm trying this:
axios.get(`${API_BASE}/Config`, { headers: { Authorization: AuthStr } })
.then(response => {
if (response.status === 200) {
commit(HIDE_LOADING)
resolve(response.data)
}
})
Where AuthStr is being passed in as an argument and is the correct Bearer Token for this endpoint. But when I call this method, axios is sending the Bearer Token configured on axios.defaults.headers.common['Authorization'] and is ignoring my AuthStr token argument.
How can I override this?

As pointed out by #Maaz Syed Adeeb this is an axios bug. I could solve using the following code as suggested in: issue
axios.get(`${API_BASE}/EndPointThatUserAnotherToken`, getAxiosOptions(AuthStr))
.then(response => {
if (response.status === 200) {
commit(HIDE_LOADING)
resolve(response.data)
}
})
function getAxiosOptions (authToken) {
let opt = {
transformRequest: [function (data, headers) {
delete headers.common.Authorization
headers.Authorization = authToken
return data
}]
}
return opt
}

Related

how can i send token to backend i n vue js

i'm trying to make payment to my backend, but each time i send the payment i get this message from my backend
{
"success": false,
"message": "No token Provided"
}
my backend requires authentication
this is my script tag
methods: {
sendTokenToServer(charge, response) {
const token = localStorage.getItem("token");
axios
.post(`http://localhost:5000/api/pay`, {
headers: {
Authorization: "Bearer" + token,
"x-access-token": token
},
totalPrice: this.getCartTotalPriceWithShipping,
})
.then(res => {
console.log(res);
});
}
}
};
</script>
when i check my dev tool i see my token
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ"
this is my backend headers
let token = req.headers["x-access-token"] || req.headers["authorization"];
please how can i go about this
your code looks fine, just create an object then add it to the url i guess your looking for something like this.. try this
methods: {
sendTokenToServer(charge, response) {
var request = {
totalPrice: this.getCartTotalPriceWithShipping,
};
const token = localStorage.getItem("token");
axios
.post(`http://localhost:5000/api/pay`,request, {
headers: {
Authorization: "Bearer" + token,
"x-access-token": token
},
})
.then(res => {
console.log(res);
});
}
}
First parameter is your url,
Second parameter is your data,
Third parameters is your config.
You can make a post request like below
axios
.post(
`http://localhost:5000/api/pay`,
data,
{
headers: {
"Authorization": `Bearer ${token}` //mind the space before your token
"Content-Type": "application/json",
"x-access-token": token,
}
}
);
NOTE: data is your request body.
e.x.
{
"firstname": "Firat",
"lastname": "Keler"
}

Server returns status 403 forbidden when i send request with bearer token

I'm working with security and have a task which is bind to jwt. When i received jwt and have already saved it in LocalStorage, i was trying to send requests to the server and put this jwt in headers: Authorization: "bearer " + jwt, but server only returned status 403 forbidden. I thought, that the reason is in requests that sending earlier then token was put in header, but i've tried to put this token artificially and server also returned 403, in postman everything works well
this is my axios instance
const TOKEN_STRING = localStorage.getItem("jwt") || ""
export const axiosInstance = axios.create({
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: "Bearer " + TOKEN_STRING,
},
})
thats how i save token in the login page
const submit = async () => {
try {
await axios
.post(baseUrl + "/api/login", loginData)
.then((res) => localStorage.setItem("jwt", res.data.jwt))
} catch (e) {
setError(e.message)
}
}
and this how i send request, which is after login page so as i think should be after localStorage receives token
const fetchData = async () => {
try {
await axiosInstance
.get(process.env.REACT_APP_BASE_BACKEND_URL + "/api/discounts")
.then((response) =>
setDiscounts(() =>
response.data.map((el, index) => ({
...el,
img: cardImages[index],
}))
)
)
} catch (e) {
setDiscountsFetchError(e.message)
}
}
useEffect(() => {
fetchData()
}, [])
i think it's enough for example but if smbd needs more info i'll give
I think you creating the axios instance way before your login call so the jwt is empty at that time.
Try the following in your fetch data request after login call, when jwt is present in local storage.
axiosInstance
.get(
process.env.REACT_APP_BASE_BACKEND_URL + "/api/discounts",
{
headers: {
Accept: "application/json",
"Content-Type": "application/json"
Authorization: 'Bearer ' + localStorage.getItem("jwt")
}
})

How to get data in the axios header to a component in Vue

I have an axios apiClient and I'm trying to get the email stored in localStorage into the header. In my component I tried using
response.headers['email']
and assigning it to an email variable but I'm getting undefined. I'm getting the email in localStorage but not able to get it in the component. Any help will be greatly appreciated.
Axios
const apiClient = axios.create({
baseURL: `${API}`,
withCredentials: false,
headers: {
Accept: "application/json",
"Content-Type": "application/json"
}
});
apiClient.interceptors.request.use(function (config) {
let token = JSON.parse(localStorage.getItem('token'));
let email = JSON.parse(localStorage.getItem('email'));
if (token) {
config.headers.Authorization = `Bearer ${token}`;
config.headers.email = `${email}`;
}
return config;
}, function (err) {
return Promise.reject(err);
});
Here is the method in my component where I need the email data
methods: {
getOrders(){
service.getAllOrders()
.then(response => {
this.email = response.headers['email'];
console.log("email:", this.email)
})
}
}
getAllOrders() does an axios get.
You set the request interceptor but you're checking the response header, and those are two different objects. The response is from the server and won't be affected by a request interceptor.
You can create a different interceptor for the response:
apiClient.interceptors.response.use((response) => {
response.headers.email = JSON.parse(localStorage.getItem('email'));
return response;
});

Axios headers being sent as payload

I'm using axios to send a post request, here's my code:
const getHeaders = (token) => {
const headers = {
"content-type": "application/json",
}
if (token !== undefined) headers.Authorization = `Bearer ${token}`;
return headers;
}
const post = async ({ url, body = {}, token }) => {
const requestObject = {
headers: getHeaders(token),
...body
}
console.log(requestObject);
return await axios.post(url, requestObject);
}
This works when there's no token (for example, the login request), it sends it alright. However, for the next request, I pass a token to request the user details (for example), but when I look at the Chrome network tab, I see this:
So, the headers are being sent as the payload, but then, in the request headers, the "Authorization: Bearer ..." is not there. What am I doing wrong?
If you want to send options you need a third argument....
const post = ({ url, body = {}, token }) => {
const options = {
headers: getHeaders(token)
}
return axios.post(url,body, options);
}
Also async/ await makes no sense here

Unhandled Rejection Type Error from API fetch

I got a weird error while working on my Spotify Web Application. I try to save a playlist to my account, which has to fetch the id element from the https://api.spotify.com/v1/me endpoint, then apply the playlist to your account. Everything seems fine otherwise, besided the fetch to that endpoint, which throws the error:
Spotify.js:81 Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'Window': The provided value is not of type '(sequence<sequence<ByteString>> or record<ByteString, ByteString>)'
I've never seen this error before, and am not sure why it's happening. The findUserId method is:
findUserId() {
if(accessToken === undefined) {
this.getAccessToken();
}
console.log(accessToken);
let userId;
fetch(`https://api.spotify.com/v1/me`, {headers: `Bearer ${accessToken}`}
).then(response => {return response.json()}
).then(jsonResponse => {
userId = jsonResponse.id;
});
console.log(userId);
return userId;
}
First, you have to set the Authentication header inside headers. Also, fetch is async, which means that you try to log userId before the network request has finished. To fix that, put your log inside the second then callback and return the fetch:
findUserId() {
if (accessToken === undefined) {
this.getAccessToken();
}
console.log(accessToken);
return fetch(`https://api.spotify.com/v1/me`, {
headers: { Authentication: `Bearer ${accessToken}` }
})
.then(response => response.json())
.then(jsonResponse => {
userId = jsonResponse.id;
console.log(userId);
return userId;
});
}
Then you can use findUserId like this:
async otherFunction() {
const userId = await this.findUserId();
console.log(userId);
}
or like this:
otherFunction() {
this.findUserId().then(userId => console.log(userId));
}
headers should be an object - change
{headers: `Bearer ${accessToken}`}
to
{headers: {'Authorization': `Bearer ${accessToken}`}}
That's not how you do headers with fetch. I think you mean to set the authorization header. See https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Headers
edit: wrong link

Categories