Reactjs fetch headers not working properly - javascript

I'm trying to use fetch with react to get a response from an aws api gateway endpoint. I'm using custom authorizer with the endpoint. I can use curl with headers to successfully get data from the endpoint, as well as use the chrome extension postman to get the data successfully, but using the below code with react, I always get a 401 error even with a valid token. I'm somewhat new to react, but I think I have code that should work. What am I doing wrong? Is there something I need to change?
componentDidMount() {
Auth.currentAuthenticatedUser()
.then((res) => {
let token = res.signInUserSession.idToken.jwtToken
///*
let myHeaders = new Headers();
myHeaders.append('authorization', token)
myHeaders.append('type', 'TOKEN')
fetch(<URL>, {headers: myHeaders})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
})
})
.catch((err) => {
console.log(err);
})
}

It looks like you need to enable CORS: http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

Related

Getting this error message 'TypeError: Failed to fetch'

While trying to fetch images from cloudinary getting this error 'TypeError: Failed to fetch'. Its a MERN project.
const fetchPosts = async () => {
setLoading(true);
try {
const response = await fetch("http://localhost:8080/api/v1/post", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
if (response.ok) {
const result = await response.json();
setAllPosts(result.data.reverse());
}
} catch (err) {
alert(err);
} finally {
setLoading(false);
}
};
This is likely an issue with what you're receiving from the backend. Check CORS headers, the HTTP method the backend expects, the URL, etc.
See this link for some more possible answers: https://bobbyhadz.com/blog/javascript-typeerror-failed-to-fetch-cors
Failed to fetch issue is the most probably because of CORS , please make sure that your backend should allow requests from your domain. Also please check the response that has been sending from backend api.
My IP address wasn't added to mongodb, once it was added the issue got resolved.

SharePoint cannot get Access Token with JavaScript?

I need to get access token from SharePoint, In order to upload some files!
I got access token from postman successfully, But when I try to do the same request with Javascript!
const generateToken = async () => {
const headers = { "Content-Type": "application/x-www-form-urlencoded" };
var formdata = {};
formdata["grant_type"] = "client_credentials";
formdata["client_id"] = "<client_id>";
formdata["client_secret"] = "<client_secret>";
formdata["resource"] =
"00000003-0000-0ff1-ce00-000000000000/site_url#tenant_id";
const body = Object.keys(formdata)
.map((key) => `${key}=${formdata[key]}`)
.join("&");
var requestOptions = {
method: "POST",
headers,
body,
};
await fetch(
"https://accounts.accesscontrol.windows.net/<tenant_id>/tokens/OAuth/2",
requestOptions
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
};
generateToken();
when I execute the page which have this script I got this error
error TypeError: Failed to fetch
at generateToken
But IDK why the respose status is 200 OK, without returning body which contain access_token
Any help is much appreciated!
You cannot get the token from javascript like that, only from single page applications because of the security issues: you expose your client secret.
You can use Microsoft Authentication Library (MSAL) for JS instead.

"POST http://localhost:4000/api/upload_file net::ERR_BLOCKED_BY_CLIENT" when post formdata via fetch

I am trying to make file upload app with containerized React & Node.js.
I got stuck with the error when I try to upload file.
The developer console says like this on the VPS server.
POST http://localhost:4000/api/upload_file net::ERR_BLOCKED_BY_CLIENT
I built Node.js docker container at http://localhost:4000 and accepts post request to the route /api/upload_file and React container at http://localhost:3000 which accepts get request to the frontend.
My frontend javascript file related to fetch is here.
const TARGET = process.env.TARGET || 'localhost:4000'
export default async function uploadFile(formData) {
const fetchedData = await fetch(`http://${TARGET}/api/upload_file`, {
method: 'POST',
body: formData
})
.then((response) => {
if (response.ok) {
return response.json()
} else {
throw new Error('Something went wrong')
}
})
.then(res => {
return {
filename: res?.filename
}
})
.catch((error) => {
console.log(error)
})
return fetchedData
}
I searched for the solutions, but it seems browser's adblocker causes the error... I tried Chrome, Firefox and Brave, and had the same results.

Difference between Python requests POST and axios POST

I am having a difficult time understanding why my API call does not work in axios (relatively new to JS). I have built an API server that takes in an Authorization header with a JWT token.
Here is my POST request workflow in Python:
resp = requests.post('http://127.0.0.1:8000/api/v1/login/access-token', data={'username': 'admin#xyz.com', 'password': 'password'})
token = resp.json()['access_token']
test = requests.post('http://127.0.0.1:8000/api/v1/login/test-token', headers={'Authorization': f'Bearer {token}'})
# ALL SUCCESSFUL
Using axios:
const handleLogin = () => {
const params = new URLSearchParams();
params.append('username', username.value);
params.append('password', password.value);
setError(null);
setLoading(true);
axios.post('http://localhost:8000/api/v1/login/access-token', params).then(response => {
console.log(response)
setLoading(false);
setUserSession(response.data.access_token);
props.history.push('/dashboard');
}).catch(error => {
setLoading(false);
console.log(error.response)
if (error.response.status === 401) {
setError(error.response.data.message);
} else {
setError("Something went wrong. Please try again later.");
}
});
}
// the above works fine
// however:
const [authLoading, setAuthLoading] = useState(true);
useEffect(() => {
const token = getToken();
if (!token) {
return;
}
axios.post(`http://localhost:8000/api/v1/login/test-token`, {
headers: {
'Authorization': 'Bearer ' + token
}
}).then(response => {
// setUserSession(response.data.token);
console.log('we made it')
setAuthLoading(false);
}).catch(error => {
removeUserSession();
setAuthLoading(false);
});
}, []);
if (authLoading && getToken()) {
return <div className="content">Checking Authentication...</div>
}
// RETURNS A 401 Unauthorized response...
What is different about the two above requests? Why does the axios version return different results than requests?
In my API, CORS have been set to *, and I know that the token within Axios is being saved properly in sessionStorage.
Any ideas?
As far as I can see you are passing your username and password in axios as params and as body data in your python request, I am not sure if your backend expects it as params or body data but try changing const params = new URLSearchParams(); to
const params = new FormData(); if the problem is that the backend isn't getting the body data it needs. The best thing I could recommend is checking your browser network tab and seeing what exactly the problem is when you hit your server.

Unauthorized when fetching Tasks with Microsoft graph

I want to fetch my tasks within Javascript and possibly add new ones, but let's focus on fetching a task.
I made an app and use the msal.js file to get a token. I get prompted to allow the app to read/write from my account, the popup closes and I've obtained a token!
So far so good, but when I try to fetch my tasks the API responds with "unauthorized". When I check the headers I can see I sent along "bearer [token]" however.
I'm completely clueless on how to get my tasks by now since I did get a proper token and I've followed the guided setup to make sure I send along the token.
In my app (which I created on https://apps.dev.microsoft.com) I've set all Task related permissions and User.read for good measure. As for the platform I've set "Web".
Is there something I'm missing or mis-configuring?
My init method:
const self = this
this.userAgentApplication = new Msal.UserAgentApplication(this.clientID, null, function (errorDes, token, error, tokenType) {
// this callback is called after loginRedirect OR acquireTokenRedirect (not used for loginPopup/aquireTokenPopup)
})
this.userAgentApplication.loginPopup(['Tasks.readwrite']).then(function (token) {
let user = self.userAgentApplication.getUser()
if (user) {
self.token = token
localStorage.setItem('token', token)
self.getTasks()
}
}, function (error) {
console.log(error)
})
My getTasks method:
const bearer = 'Bearer ' + this.token
let headers = new Headers()
headers.append('Authorization', bearer)
let options = {
method: 'GET',
headers: headers
}
// Note that fetch API is not available in all browsers
fetch('https://outlook.office.com/api/v2.0/me/tasks', options).then(function (response) {
let contentType = response.headers.get('content-type')
if (response.status === 200 && contentType && contentType.indexOf('application/json') !== -1) {
response.json().then(function (data) {
console.log(data)
})
.catch(function (error) {
console.log(error)
})
} else {
response.json().then(function (data) {
console.log(data)
})
.catch(function (error) {
console.log(error)
})
}
})
.catch(function (error) {
console.log(error)
})
Your token is scoped for Graph, not Outlook. Tasks.readwrite will default to the Microsoft Graph and won't work against the Outlook endpoint.
Change this bit:
this.userAgentApplication.loginPopup(['Tasks.readwrite'])
To:
this.userAgentApplication.loginPopup(['https://outlook.office.com/Tasks.readwrite'])
You are trying to use Microsoft Graph, so the request should look like
GET https://graph.microsoft.com/beta/users/{id|userPrincipalName}/outlook/tasks
It's documented here:https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/outlookuser_list_tasks
I believe you got a Microsoft Graph token but you're trying to use it on the Outlook REST endpoint, which would not work.

Categories