Cookies are not set in browser - reactjs

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.

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}`
},
})

Fetch isn't setting cookies

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' },
})

Set cookie from API response in React

I have a React app, and an API. When i POST data to APIs login url API responses me back with cookie on successful login, which I have to set, so in each next request user will send this cookie. But I can't find a method to get it from response.
I want to set sessionid, but I can't reach it within code. I tried to do
Cookies.set('sessionid', response.headers['sessionid']);
But it sets undefined. console.log(response.headers) also gives me {content-length: "31", content-type: "application/json"}. Do I do something wrong?
Sender function:
formSender() {
const url_to_send = `${this.state.api_base_url}:${this.state.api_base_port}${this.state.api_user_url}/login/`;
axios.post(url_to_send, `username=${this.state.username}&password=${this.state.password}`, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
.then((response) => {
// I need to set the cookie here
this.setState({
login_success: response.status === 200,
request_sent: false
});
})
};
Try to set Access-Control-Expose-Headers in the back end or
await axios({
method: 'post',
url: YOUR_URL,
data: Data,
headers: { 'Authorization': 'TOKEN' }
});
I have the same problems and i do that for resolve in backend:
app.use(cors({
origin: true,
credentials: true
}));
and the axios request :
axios({
method: "post",
url: `http://localhost:5500/api/user/login`,
withCredentials: true,
data: {
email,
password,
},
headers: {
"Content-Type": "application/json",
}
})
.then((res) => {
console.log(res);
})
I was initially looking for a solution to setting a cookie from a response, but I realized if it's passed as a Set-Cookie header then it is set by the browser. No need to set it manually. Here is the console view
My app looks something like this:
const app = express();
app.use(cors({
origin: ['http://localhost:3000'],
methods: ['POST', 'PUT', 'GET', 'OPTIONS', 'HEAD'],
credentials: true,
}))
app.use(cookieParser())
app.get('/foo', verifyToken, (req, res) => {
// you can omit verifyToken if you want, it's for bearer auth.
if (true) {
res.cookie('XSRF-TOKEN', 'example')
res.send('Welcome')
} else {
res.sendStatus(403);
}
});
The React side:
<Button onClick={() => {
axios.get('http://localhost:8081/foo', {
params: {},
headers: {
Authorization: `Bearer 123`,
// again, omit ^ if you're not doing bearer auth
},
withCredentials: true,
}
).then((response) => {
console.log('cookie should be set')
})
}}>Express cookie</Button>
Bear in mind if you're deploying to a server both react and express should be on an https connection. Connecting http <-> https causes other issues with cookies.

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

React native fetch() 403 status

I have an API endpoint working good in postman with the bellow options
The above request can get 200 status and got a response. Now I am trying to implement the same API with React Native using fetch method.
fetch('https://example.com/api/user/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Token':'xxxxxx-xxxx-xxxx-xxxx-xxxxx'
},
body: {
"useremail": "testuser#example.com",
"userpassword": "123456"
},
})
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
}).catch((error) =>{
console.error(error);
});
The above code was not working and I am getting 403 status.
Have you tried this
The easy way to implement this is to use this attribute to your AndroidManifest.xml where you allow all http for all requests:
android:usesCleartextTraffic="true"
feel free for doubts
You are passing data without converting it to json will make problem here
fetch('https://example.com/api/user/login', {
method: 'POST',
credentials : 'include',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'token':'xxxxxx-xxxx-xxxx-xxxx-xxxxx',
},
body: JSON.stringify({ // convert object to json
"useremail": "testuser#example.com",
"userpassword": "123456"
}) ,
})
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
}).catch((error) =>{
console.error(error);
});
HTTP 403 is a standard HTTP status code communicated to clients by an HTTP server to indicate that access to the requested (valid) URL by the client is Forbidden for some reason. The server understood the request, but will not fulfill it due to client related issues.
so for first step in your postman use a fake user password to see if you get 403 again ,
if you got, that means you have problem in your sending your react native data.
so you should focus on your sending request code then,
According to docs
you can post like this
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});
be sure that you are sending your user pass correctly and not missing anything like misspellings
hope this helps you.

Resources