React native - FETCH - Authorization header not working - reactjs

I made a server query via an app developed using react-native. I used fetch API and it turns out any query with authorization header not working. POST and GET method REQUESTS that don't expect Authorization headers at the server side works well. Some Queries at the server side are protected with authorization and when I make such queries including authorization header, I always get '401:unauthorized' error.
But such queries works well with POSTMAN. Any suggestions here would be of great help.
getThingsApi() {
let uri = "https://example.com/things/";
let req = {
method: "GET",
credentials: "include",
//mode: "no-cors",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
//'Access-Control-Request-Method': 'GET',
//'Access-Control-Request-Headers': 'origin, x-requested-with',
'Origin': '',
'Host':'example.com',
'authorization': 'Basic '+Base64.btoa('aaa:bbb'),
'Cache-Control': 'no-cache'
}
};
fetch(uri, req)
.then(response => response.json())
.then(responseJson => {
console.log("ResponseAxis::" + JSON.stringify(responseJson));
console.log("ResponseAxis::" + JSON.stringify(responseJson));
alert("ResponseAxis::" +JSON.stringify(responseJson));
})
.catch(error => {
console.log("Error::" + JSON.stringify(error));
});
}

Issue is fixed. We used Fetch API and fetch Api converts all headers into lower-case(eg: authorization) and the server side expects upper-case starting letter(eg: Authorization). After changing the server side code to be case-insensitive, everything works fine.

Related

Wrong credentials in REST fetch with multiple users per session

I have a webapp (using react, redux) that fetchs data via REST. Everything works fine as long as I'm only logging in one user per session. If I'm logging in multiple users at once using the same browser, in the BE (java with spring) the wrong principal (always the principal for the latest logged in user) is received.
How I can send the correct credentials for each user?
FE:
public restPost(url: string, request: any): Rx.Observable<any> {
return Rx.Observable.create(
(observer: Rx.Observer<any>) => {
fetch(url, {
method: 'POST',
mode: 'cors',
credentials: 'include',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then((response: Response) => {
// handle response
})
.catch(error => observer.error(error));
}
);
}
BE:
#RequestMapping(value="/test", method = RequestMethod.POST)
#CrossOrigin(origins = "*")
public ResponseEntity<Test> test(#RequestBody TestRequest testReq, HttpServletResponse response, #AuthenticationPrincipal Principal principal) {
// at this point the principal.getName() has the name of the latest logged in user
// return the response
}
My solution (only working because I have also have a websocket connection):
added a bearer token to the REST headers in the FE:
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: header ? ('Bearer ' + header.token) : ''
}
In the BE I saved a map with token to principals which I could then access for REST messages

What is the best way to enable CORS in React Application?

There are different ways to make a REST call in react-
e.g
axios.post('link', JSON.stringify(data1),
{
headers: {"content-type" : "application/json", "Access-Control-Allow-Origin" : "*"}})
.then(response => {
console.log("res:", response)
})
.catch(err =>{
console.log(err)
})
}
OR
fetch('http://localhost:8080/feedbacks/addfeedback', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin' : '*'
},
body:body
What is the most effiecient way to enable CORS.
Is there any other way that I can do this either in frontend or backend?
It depends on what HTTP library you are using.
See What is difference between Axios and Fetch?.
I usually use Axios, next what i do is creating a global instance and configuring Axios once.
export const api = axios.create({
baseURL: '_URL_',
timeout: 1000,
withCredentials: false,
responseType: 'json',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*' // whatever you want
}
});
// You can add common headers later
api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
Also i'm enabling CORS on my server side application.
Thanks to #henrik123 for good explanation:
The browser is going to see that some Javascript request has tried to initiate a request to a different domain, subdomain or port than what the browsers is currently at. If any of these things are different, the CORS kicks in. Doesn't matter if you use Axios, Fetch or any other other library

Can't send auth headers with axios

Can't send authorization header with rest API. Got 'OPTIONS' error with status 0. All headers and options are allowed on the server. Server is written on PHP.
Here is my request:
axios.post(`${API_URL}users/${23}/profile/main/update`,
{formData},{
headers:{ 'Content-Type':'multipart/form-data',
Authorization:`Bearer ${token}`}
})
It seems like it does not send the header when there is authorization. However, it works, if i delete authorization, and leave only content type
This should do the trick
axios({
method: 'POST',
url:`${API_URL}users/${23}/profile/main/update`,
headers: {
'Content-Type':'multipart/form-data',
'Authorization':`Bearer ${token}`},
data: formData
})
Refer docs for browser
Try to send as below:
var headers = {
'Content-Type': 'multipart/form-data',
'Authorization': `Bearer ${token}`
}
axios.post(`${API_URL}users/${23}/profile/main/update`,
{formData}, headers)
Try using Ajax call below:
import $ from 'jquery';
$.ajax({
url:`${API_URL}users/${23}/profile/main/update`,
processData: false,
contentType: false,
data : formData,
method : "POST",
headers: {
"Authorization": `Bearer ${token}`
}
});
I had this same issue, it is possible that you are not passing the sent auth header from your apache config to your php application.
you might need to set
WSGIPassAuthorization On
inside your virtualhost config.
Check this

Mailchimp api not working with fetch and Reactjs

I cannot get the fetch api to work with the mailchimp api in React. I'm also using webpack to run a devserver.
This is what I have:
componentDidMount() {
let authenticationString = btoa('123:myapikey-us17');
authenticationString = "Basic " + authenticationString;
fetch('https://us17.api.mailchimp.com/3.0/lists/fakelistid/segments', {
mode: 'no-cors',
method: 'GET',
credentials: 'same-origin',
headers: new Headers({
'Authorization': authenticationString,
'Accept': 'application/json',
'Content-Type': 'application/json'
})
}).then(function(e){
console.log("fetch finished")
}).catch(function(e){
console.log("fetch error");
})
}
I've tested the exact same api request in Postman and that works fine.
When I try this in React I keep getting a 401 status code saying "Your request did not include an API key."

react fetch header not set

I am facing a problem. And the solutions that are accepted by the others, those don't work for me./
I have:
return await fetch(url, {
method: httpMethod,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'x-test':'try me',
},
body: JSON.stringify(bodyObject)
});
But, it seems like no header is set at all.
Cors-header is set, adding mode:'cors' makes no difference.
Am I missing something?
the request:
Accept is empty and Content-Type nor x-test are nowhere to be found.
..
Edit
..
If i need to create new question, do tell me.
New request
So I see that the header is set - thanks to liminal18!-. However, now i want to authorize to an AD.
so now I got:
async callUrl(url, httpMethod, bodyObject) {
try {
var requestObj = {
method: httpMethod,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'x-test':'try me',
'Authorization': 'Basic Uk11bGxlc....'
}
};
if (bodyObject !== undefined){
requestObj.body = JSON.stringify(bodyObject);
}
return await fetch(url, requestObj);
} catch(error){
console.error(error);
}
}
But still get an 401.
I know this is not the clean solution for logging in, but just testing..
Are you sure the request you captured is the correct request?
if you're using CORS there is an OPTIONS post to get the cors allowed methods before react will post/put which might be what you are looking at and not the actual post or put you intended. Where are the CORS headers set?

Resources