Reputation: 1823
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?
Upvotes: 61
Views: 159175
Reputation: 468
In order to set a default header on your fetch request you have two choices:
The best solution, while it may look like a simple task at forst glance, it can get quite tricky. You might use a library instead, I wrote this one.
Always keep in mind this one thing: your auth header has to be dynamic, you should read it everytime you make a fetch request. In order to stay safe, read it in a function call
const withDefaults = (headers) => {
// for the Auth header make sure to read the value dynamically inside this function
// if you were to read it outside the value would never change
// the following also works with cookies
const authHeader = localStorage.getItem('auth-header')
// transform the headers from the params in an Header instance
// this formats the keys in a consistent way
// eg both 'content-Type' and 'Content-type' are transformed to 'Content-Type'
const headersInstance = new Headers(headers)
// add the Authorization header if the headersInstance do not have it
if(!headersInstance.has('Authorization')){
headersInstance.set('Authorization', authHeader)
}
return headersInstance
}
Usage
fetch('url here', {
headers: withDefaults({ 'content-type': 'application/json' }),
// ...other options
method: 'POST',
body: { hello: 'world'}
})
Our solution is not really reusable, the default headers are hard coded into our function
To solve that issue we can use a factory function
const createWithDefaults = (getDefaultHeaders) => {
return (headers) => {
const headersInstance = new Headers(headers)
new Headers(getDefaultHeaders()).forEach((val, key) => {
if(!headersInstance.has(key)) {
headersInstance.set(key, val)
}
})
return headersInstance
}
}
Notice that getDefaultHeaders
is a function, this makes sure the default headers stay dynamic: they are evaluated inside if withDefaults
const withDefaults = createWithDefaults(() => ({
Authorization: localStorage.getItem('auth-header'),
// other default headers
}))
// then do the same as before
fetch('url here', {
headers: withDefaults({ 'content-type': 'application/json' }),
// ...other options
method: 'POST',
body: { hello: 'world'}
})
This way we never need to change the internals of the functions. We only need to change the arg passed to createWithDefaults
Upvotes: 0
Reputation: 57023
Existing answers show the header but are either incomplete, promote poor practices and/or have irrelevant information.
Here's a minimal, complete, runnable example:
const url = "https://httpbin.org/bearer";
const token = "foobar";
fetch(url, {
// credentials: "include", // may not be necessary
headers: {
Authorization: `Bearer ${token}`,
}
})
.then(response => {
if (!response.ok) {
throw Error(response.status);
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => console.error(error.message));
Upvotes: 0
Reputation: 61
headers: {
'Authorization': `Bearer ${localStorage.getItem("token")}`,
'Accept': 'application/json',
'Content-Type': 'multipart/form-data;
},
Upvotes: 6
Reputation: 2131
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
}));
Upvotes: 90
Reputation: 18556
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) });
Upvotes: 19
Reputation: 6280
You can pass headers as second parameter of fetch:
fetch(<your url>, {
headers: {
authorization: <whatever is needed here>
}
})
Upvotes: 6