I have a Node/Express backend and I'm consuming the API with a React Client. I want to be able to set the authorization header after a user is signed up. This ensures that subsequent requests are sent with the authorization header.
I can see how it's done in Axios here and how to retrieve the authorization header in Fetch here
Is it possible to do this with Fetch API and how?
Thank you in advance.
var url = "https://yourUrl";
var bearer = 'Bearer ' + bearer_token;
fetch(url, {
method: 'GET',
withCredentials: true,
credentials: 'include',
headers: {
'Authorization': bearer,
'X-FP-API-KEY': 'iphone', //it can be iPhone or your any other attribute
'Content-Type': 'application/json'
}
}).then(responseJson => {
var items = JSON.parse(responseJson._bodyInit);
})
.catch(error => this.setState({
isLoading: false,
message: 'Something bad happened ' + error
}));
As far as I know, there's no way to use default options/headers with fetch. You can use this third party library to get it to work, or set up some default options that you then use with every request:
// defaultOptions.js
const defaultOptions = {
headers: {
'Authorization': getTokenFromStore(),
},
};
export default defaultOptions;
Then use the default options like:
import defaultOptions from './defaultOptions';
// With default options:
fetch('/auth', defaultOptions);
// With additional (non-default) options:
fetch('/auth', { ...defaultOptions, body: JSON.stringify(additionalData) });
You can pass headers as second parameter of fetch:
fetch(<your url>, {
headers: {
authorization: <whatever is needed here>
}
})
headers: {
'Authorization': `Bearer ${localStorage.getItem("token")}`,
'Accept': 'application/json',
'Content-Type': 'multipart/form-data;
},
In my case, the problem was that the string I was setting as the Authorization was not yet generated. I had to wrap it in a promise, and suddenly it worked.
let authHeader: string = await SearchAuthService.getAuthHeader();
Related
I am trying to set up authentication with Remix as my pure frontend and a django backend.
When the user signs in successfully, the backend sends a cookie with the response and this is set in the browser redirect with remix
const signIn = async (credentials: LoginCreds) => {
try {
const response = await fetch(generateFullBackendUrl('/auth/signin'), {
method: 'POST',
body: JSON.stringify(credentials),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
credentials: 'include'
});
return response;
} catch (e) {
console.log(e);
}
}
const response = await authService.signIn({
email,
password
})
const cookies = response?.headers.get('set-cookie');
if(cookies){
return redirect('profile', {
headers: {
'Set-Cookie': cookies
}
});
However when I try to make subsequent fetch calls in my loader the cookies are not sent to the backend as I would expect the browser would
await fetch(generateFullBackendUrl('api/users/me'), {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
credentials: 'include'
})
Front end is running on port 3000
Backend running on port 4000
Im wondering why the fetch request in the loader does not send the cookies with the request
You need to read the cookie header from the loader request and pass it to your fetch headers.
There’s no way Fetch can automatically know what headers to send when used server side.
There is a quick workaround but not so elegant solution:
in your loader use this:
export const loader: LoaderFunction = async({request}) => {
const response = await fetch(`/api/books?${new URLSearchParams({
limit: '10',
page: '1',
})}`, {
headers: {
'Cookie': request.headers.get('Cookie') || ''
}
});
console.log(response)
if(response.ok) return await response.json();
}
This bug has caused serious trouble for me. Finally i was able to get to the root of it.
(A similar version of bug has been reported in GitHub but it has been marked as fixed)
Axios will fail to set the correct header type and goes for default header type when transformRequest is used.
I am not sure what exactly is causing this issue but here is a quick way of reproducing the issue.
Here i have defined an axiosInstance
const axiosInstance = axios.create({
baseURL: baseURL,
timeout: 360000,
transformRequest: [
function (data, headers) {
const accessToken = window.localStorage.getItem('access_token');
if (accessToken) {
headers['Authorization'] = `Bearer ${accessToken}`;
} else {
delete headers.Authorization;
}
return JSON.stringify(data);
},
],
headers: {
'Content-Type': 'application/json',
accept: 'application/json',
Authorization: `Bearer ${window.localStorage.getItem('access_token')}`,
},
});
Now i have to send multipart/form-data.
let formData = new FormData();
formData.append('profile_pic', file, file.name);
axiosInstance
.put('http://127.0.0.1:8000/users/profile-pic-upload/', formData)
.then((res) => console.log(res))
.catch((err) => alert(err));
Since formData is contains image here i expected the axios to override the default header's content-type from 'application/json' to 'multipart/form-data'. But it turns out the content-type in the sent request packet is still 'application/json'.
But when i comment out the transformRequest section. Surprisingly it correctly sets the content-type to 'multipart/form-data'.
const axiosInstance = axios.create({
baseURL: baseURL,
timeout: 360000,
transformRequest: [
// function (data, headers) {
// const accessToken = window.localStorage.getItem('access_token');
// if (accessToken) {
// headers['Authorization'] = `Bearer ${accessToken}`;
// } else {
// delete headers.Authorization;
// }
// return JSON.stringify(data);
// },
],
headers: {
'Content-Type': 'application/json',
accept: 'application/json',
Authorization: `Bearer ${window.localStorage.getItem('access_token')}`,
},
});
I am using axios 0.20 (i noted that axios 0.21 also has same issue as well).
I found a similar issue on Github it says it has been fixed in axios 0.20
https://github.com/axios/axios/issues/2623
Please confirm that whether this is an existing bug or am i doing something wrong.
I have written more detailed description in my previous stackoverflow post.
AxiosInstance setting default type to "application/x-www-form-urlencoded" instead of expected "multipart/form-data"
I used the format provided in this spotify web api reference and an access token generated from there directly, but I keep getting a 401 error. What is going on?
const accessToken = 'string from https://developer.spotify.com/console/get-current-user-playlists/?limit=50&offset=0';
console.log(accessToken);
axios
.get(
'https://api.spotify.com/v1/me/playlists',
{ params: { limit: 50, offset: 0 } },
{
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + accessToken,
'Content-Type': 'application/json',
},
}
)
.then((data) => console.log(data))
.catch((err) => console.log(err));
Error:
GET https://api.spotify.com/v1/me/playlists?limit=50&offset=0 401
Figured it out. Post requests have a body in the second param and headers for the third param. Get requests, however, have only the second param for both the URL parameters and headers. So I just had to combine the 2 objects into one:
axios
.get(
'https://api.spotify.com/v1/me/playlists', {
params: { limit: 50, offset: 0 },
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + newAccessToken,
'Content-Type': 'application/json',
},
})
)
Figured it out. Post requests have a body in the second param and headers for the third param. Get requests, however, have only the second param for both the URL parameters and headers. So I just had to combine the 2 objects into one
I am new to React, And I am Stuck. I am trying to make a signup page, having textboxes: name,phonumber,email,password.
What I want is, When I click on login button, all these details should be sent over POST to my API, and response is fetched and stored.
API:
http://localhost:5000/api/users/signup
Method:
POST
Request to my api is send in this way:
content-type: application/json
{
"name": "Devanshh Shrivastvaaaa",
"phoneNumber":"982964XXX8",
"email": "devannnnnshh;#ccc.in",
"password": "1234566788"
}
Can anyone please explain me using code how to send this data to my api on clicking signup, and fetching response
Don't need to use any third party libraries, just use the Javascript fetch API
// Example POST method implementation:
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
postData('https://example.com/answer', { answer: 42 })
.then(data => {
console.log(data); // JSON data parsed by `data.json()` call
});
Source: Mozilla MDN
you need to install axios or fetch axios is good axios
axios.post('http://localhost:5000/api/users/signup', {
name: "Devanshh Shrivastvaaaa",
phoneNumber":"982964XXX8",
email: "devannnnnshh;#ccc.in",
password: "1234566788"
})
.then((response) => {
console.log(response);
}, (error) => {
console.log(error);
});
also check for further
In my React project, I made an Axios call to populate a Calendar Event List taking data from Microsoft Outlook Calendar (using Microsoft API). The result is the following
As you can see only event description give me a problem. Indeed to show the event description it shows me an HTML string without the event detail.
I read that I have to put in the header of my request Content-type:text, but I tried and It doesn't work. How I can solve that? This is my Axios Request
getEvents(startDate, endDate, accessToken) {
const startDateString = startDate.toISOString();
const endDateString = endDate.toISOString();
axios.get(
`https://graph.microsoft.com/v1.0/users/${USER_PUBLIC_ID}/calendarview?startdatetime=${startDateString}&enddatetime=${endDateString}&orderby=start/dateTime`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
},
).then(response => this.setEvents(response.data.value))
.catch((error) => {
console.error(error.response);
});
}
For that matter Prefer: outlook.body-content-type="text" header needs to be specified.
According to documentation:
To specify the desired format to be returned in the Body and
UniqueBody properties in a GET request, use the Prefer: outlook.body-content-type header:
Specify Prefer: outlook.body-content-type="text" to get a message body returned in text format.
Specify Prefer: outlook.body-content-type="html", or just skip the header, to return the message body in HTML format.
Example
getEvents(startDate, endDate, accessToken) {
const startDateString = startDate.toISOString();
const endDateString = endDate.toISOString();
return axios.get(
`https://graph.microsoft.com/v1.0/users/${USER_PUBLIC_ID}/calendarview?startdatetime=${startDateString}&enddatetime=${endDateString}&orderby=start/dateTime`,
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'Prefer' : 'outlook.body-content-type="text"'
}
}
);
}
You need to give axios a config object. Currently, you are using the get property, that is why your code doesn't work currently:
axios({
url: `https://graph.microsoft.com/v1.0/users/${USER_PUBLIC_ID}/calendarview?startdatetime=${startDateString}&enddatetime=${endDateString}&orderby=start/dateTime`,
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-type": "text"
},
})
You can read more here: https://github.com/axios/axios