Saving set-cookie value to browser cookies in React - reactjs

I get this cookie value from the server and I want to save this to my browser.
Set-Cookie: succeeedd=noooo!; Path=/
I've tried with
const res = yield axios.post(`${config.authURL}/login`, data, {
headers: {
'Content-Type': 'application/json',
Cookie: 'cookie1=value',
},
});
and
const res = yield axios.post(
`${config.authURL}/login`,
data,
{
headers: {
'Content-Type': 'application/json',
},
},
{ withCredentials: true })
Both are not saving cookies into the browser cookies. How can I save Set-Cookie value to the browser so I can use them for authentication?

Pass withCredentials: true as below
const res = yield axios.post(
`${config.authURL}/login`,
data,
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true
}
);
For more generic configuration,
// You can add it in a separate config file
const request = axios.create({ withCredentials: true });
// While making API call
request.post(`${config.authURL}/login`, data, { headers: {...} });
Check here for more details.

install universal-cookie with npm
import Cookies from 'universal-cookie';
const cookies = new Cookies();
axios.post(URL, data, {
headers: {
'Content-Type': 'application/json',
},
{ withCredentials: true }
})
.then((res) => {
let name = res.data.blobName;
let value = res.data.blobValue;
cookies.set(`${name}`, `${value}`);
})
.catch(function (error) {
console.log(error);
});

Related

Axios - how to properly set cookies with same-site=None in modern browser

The scenario is that I post to the backend API and then get back the session ID, and after that, I can put it in browser cookie for another API request.
I have created an axios instance as following
const axiosInstance = axios.create({
baseURL: "https://example.com",
timeout: 120000,
withCredentials: true,
credentials: "include",
headers: {
"Content-Type": "application/json",
accept: "application/json",
},
});
axiosInstance
.post("/login-and-get-session", null, {
params: {
... some data
},
})
.then((res) => {
console.log("response post = ", res);
axiosInstance
.get("/some-get-url", {
params: {
... some data
},
})
.then((res) => {
console.log("response get = ", res);
});
});
I have searched many articles that say with withCredentials: true, the browser will automatically set cookies for us.
but I get the following message from the browser:
This Set-Cookie didn't specify a "SameSite" attribute and was default to "SameSite=Lax" .... The Set-cookie had to have been set with "Same Site=None" to enable cross-site usage.
and then I tried like
const axiosInstance = axios.create({
baseURL: "https://example.com",
timeout: 120000,
withCredentials: true,
credentials: "include",
headers: {
"Content-Type": "application/json",
accept: "application/json",
"Set-Cookie":"SameSite=None; Secure",
},
});
axiosInstance
.post("/someurl", null, {
params: {
... some data
},
})
.then((res) => {
console.log("response post = ", res);
axiosInstance
.get("/some-other-url", {
params: {
... some data
},
})
.then((res) => {
console.log("response get = ", res);
});
});
or
const axiosInstance = axios.create({
baseURL: "https://example.com",
timeout: 120000,
withCredentials: true,
credentials: "include",
headers: {
"Content-Type": "application/json",
accept: "application/json",
},
});
axiosInstance
.post("/someurl", null, {
params: {
... some data
},
})
.then((res) => {
console.log("response post = ", res);
axiosInstance
.get("/some-other-url", {
params: {
... some data
},
header: {
"Set-Cookie": `JSESSIONID=${res.sessionId} SameSite=None; Secure`,
}
})
.then((res) => {
console.log("response get = ", res);
});
});
all are no use.
how to properly set cookies in axios for modern browsers?

Connection with Basic HTTP authorization with email and password body application/x-www-form-urlencoded with axios

I am trying to create a new session with axios following this documentation:
https://www.traccar.org/api-reference/#tag/Session/paths/~1session/post
This is my code, I have really tried everything without results
const sessionurl = 'http://31.220.52.187:8082/api/session';
const params = new URLSearchParams();
params.append('email', 'admin');
params.append('password', 'admin');
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
axios
.post(
sessionurl,
{
withCredentials: true,
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*',
},
},
{
params
},
)
.then(function (response) {
console.log('Authenticated');
})
.catch(function (error) {
console.log('Error on Authentication');
});
It should be something like this:
const params = new URLSearchParams();
params.append('email', 'admin');
params.append('password', 'admin');
axios.post(sessionUrl, params);
You might need to also add a header.

React doesn't set cookies but Postman does?

I have a spring boot backend that allows a user to login.
When I use postman to send a json payload to login in a user it returns the correct response with a cookie for a JSESSION.
Postman details with response and cookie
When I send the payload in react (axios) I don't see the cookie for the JSESSION anywhere but the response is still okay ?
const API_URL = "http://localhost:8080/api/auth/";
login(uniqueId: string, password: string) {
return axios.post(API_URL + "login", JSON.stringify({
"uniqueId": uniqueId,
"password": password
}),
{
headers: {
'Content-Type': 'application/json',
'withCredentials': 'true'
}
})
.then(response => {
console.log(response);
return response;
}).catch(error => {
return error.response
});
}
Chrome tab with response and no cookie
'withCredentials': 'true' shoud be outside of headers (Request Config documentstion)
In your case it would be:
const API_URL = "http://localhost:8080/api/auth/";
login(uniqueId: string, password: string) {
return axios.post(API_URL + "login", JSON.stringify({
"uniqueId": uniqueId,
"password": password
}),
{
withCredentials: true,
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log(response);
return response;
}).catch(error => {
return error.response
});
}
another solution is create instance axios with parametr withCredentials: true (creating axios instance).
const BASE_URL = "http://localhost:8080/api/";
const api = axios.create({
baseURL: BASE_URL,
withCredentials: true,
headers: {'Content-Type': 'application/json'}
});
and then you can do:
return api.post("/auth/login", JSON.stringify({
"uniqueId": uniqueId,
"password": password
})) .then(response => {
console.log(response);
return response;
}).catch(error => {
return error.response
});
I have the same issue as mentioned, And I am also using withCredentials: true outside the header.
But still, Postman get Cookies And React App not.

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

How can I send a String to a web service using POST request (react native)?

Is it possible to send a String to a PHP web service using a POST request (react native)? I only find some JSON POST requests like the following:
functionName = async() => {
const response = await fetch('http://localhost/webservice.php', {
method: 'POST',
mode: 'no-corse',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
searchQuery: 'something',
})
})
const myData = await response.json();
this.setState({data: myData});
}
How can I transform this to send a String (like just one word) instead of a JSON String?
Something like
functionName = async() => {
const response = await fetch('http://localhost/webservice.php', {
method: 'POST',
mode: 'no-corse',
headers: {
Accept: 'application/json',
'Content-Type': 'text/plain'
},
body: 'Your text'
})
const myData = await response.json();
this.setState({data: myData});
}

Resources