Fetch isn't setting cookies - reactjs

I have a reactjs frontend running on root /.
On the same domain and server there is an Wordpress instance running under the default Wordpress slugs (/wp-admin, /wp-json, etc.). I already authenticate users via JWT over the WP API.
The problem is i need to get the Wordpress default auth cookies so users can switch between Wordpress and reactjs pages without logging in twice.
I started to add a second fetch on login which calls the /login.php route and posts login credentials as form-data. In Postman i get the body, headers and the auth cookies i need:
If i fetch this inside my react frontend i don't get the cookies, also the are not set and available under document.cookie or at the dev tools.
This is my fetch function in react which is returning the Dashboard Page as Response Data and a Status Code 200:
async handleCookies() {
const formData = new FormData()
formData.append('log', this.state.mail)
formData.append('pwd', this.state.password)
await fetch('XXX.XXX.XXX.XXX/wp-login.php', {
method: 'POST',
body: formData,
credentials: 'include',
headers: { 'Content-type': 'application/x-www-form-urlencoded', Cache: 'no-cache' },
})
.then(response => response)
.then(cookies => {
alert(cookies)
})
.catch(err => console.log(err))
}
Expectation: I expect to receive the cookies.

It turned out that i didn't passed the credentials in the right way. Now everything is working.
await fetch('XXX.XXX.XXX.XXX/wp-login.php', {
method: 'POST',
body: `log=${encodeURIComponent(EMAIL)}&pwd=${encodeURIComponent(PASSWORD)}`,
credentials: 'include',
headers: { 'Content-type': 'application/x-www-form-urlencoded', Cache: 'no-cache' },
})

Related

How do I send credentials(accessToken) with axios requests?

When users login, I send an axios post request to the login endpoint with its required credentials(accessToken). everything works fine. After a successful login, they are redirected to the homepage where I make i get request. The request doesn't send the credentials whixh of course would return an unauthenticated error. Even when I specify this in the axios get request it still woudn't work.
withCredentials: true
on postman and Insomnia, the token is sent successfully and the correct data is gotten, but It just will not work on the web. What could be wrong?
ths is the useFetch code
try {
await axios({
url: `https://crayonnne-jotter-server.herokuapp.com/api${url}`,
method: "get",
withCredentials: true,
}).then((res) => {
console.log(res)
});
} catch (err) {
console.log(err)
}
You have to provide the accessToken through the headers.
axios({
... // other stuff
headers: {
Authorization: `Bearer ${accessToken}`
},
})

React Remix not sending cookies to remote server

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();
}

Cookies are not set in browser

Been at this problem for a while, appreciate any help.
This problem is related to login request.
I am making POST request to server by axios and in the theory the session id and csrf-token should be saved in cookies. But in Application/Storage/Cookie (Google Chrome) there is no cookie.
axios({
url: URL,
contentType: "multipart/form-data",
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
withCredentials: true,
data: form
})
.then(res => {
console.log(res);
})
.catch(err => console.log(err.response.data))
Also, when I send request, I get this cookies in response in the devtool tab "Network"
SCREENSHOT
In the Mozilla Firefox and Microsoft Edge the same problem. Cookies don't store.
Hope you will help me.

API request working in Postman but not in fetch() method of React Native app

I am trying to do a fetch() method in my React Native app:
return fetch(url, {
method: method,
headers: {
'Accept': 'application/json',
...headers
},
body: body
})
Here url is <IP address>:<port>/api/token
method is 'POST'
headers is {Content-Type: "application/x-www-form-urlencoded"}
and body is
grant_type=password&username=<username>&password=<password>&pushtoken=&primaryhost=<primary host IP>&primaryport=<primary host port>&secondaryhost=<secondary host IP>&secondaryport=<secondary host port>&osscustomer=103&deviceid=<device ID>&version=1.0&osversion=9&deviceversion=1.0
When I use these values in a Postman request, it works fine, but when I run the fetch() method in my React Native app, it gives the error e = TypeError: Network request failed at XMLHttpRequest.xhr.onerror.
Does anyone know why this might be?
change 'Accept' to Accept without single quites.
In the latest android versions http requests are not allowed by default. Take a look at this post for further information about allowing http request:How to allow all Network connection types HTTP and HTTPS in Android (9) Pie?
Use the following format:
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});
Better to use axios for http/https requests:axios package
It's working fine for me. Try this it may help
const formData = new FormData();
formData.append('email', 'test#gmail.com');
formData.append('password', '123456');
fetch("https://test.com/api/login", {
method: 'post',
body: formData
})
.then(res => res.json())
.then(
(result) => {
console.log(result);
}).catch(err => {
console.log(err);
})

Azure App Service Authentication - 302 when trying to GET /.auth/me

I have a reactjs web app which is hosted on Azure App Services, using App Service Authentication.
My app authenticates properly and from inside the app I'm attempting to GET /.auth/me so that I can read the access tokens to use for some future API requests but am receiving a 302 in response. The response redirects to login.microsoft.com even though the first request (to load the app) has already been authenticated.
const headers = {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json',
'credentials': 'include'
};
return (dispatch) => {
const requestOptions = {
method: 'GET',
headers: headers,
};
return fetch("/.auth/me", requestOptions)
.then(parseResponseAndHandleErrors)
.catch(error => {
console.error(error)
});
}
I think I must be missing a cookie or a header in the GET but the docs don't give much information: https://learn.microsoft.com/en-us/azure/app-service/app-service-authentication-how-to#retrieve-tokens-in-app-code
From your client code (such as a mobile app or in-browser JavaScript), send an HTTP GET request to /.auth/me. The returned JSON has the provider-specific tokens.
I have tried setting 'credentials': 'same-origin' but that didn't make any difference.
I managed to figure this out after looking in to more detail at the 'credentials' option of the fetch() API.
'credentials' : 'same-origin' should not be included in the headers, but rather as a seperate request option:
const headers = {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
};
return (dispatch) => {
const requestOptions = {
method: 'GET',
headers: headers,
'credentials': 'same-origin' //credentials go here!!!
};
return fetch("/.auth/me", requestOptions)
......
}

Resources