React doesn't set cookies but Postman does? - reactjs

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.

Related

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.

firebase authentication rest API request with axios

I am trying to write function to Sign in user with Email and Password.
Using Axios and firebase rest API.
So this is how Axios instance looks like, really simple right? ...
const authUrl = `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${DATABASE_SECRET}`;
const baseURL = "https://beauty-wonderland-e913c-default-rtdb.firebaseio.com";
export const getAxios = (token = null) => {
const config = {
baseURL: baseURL,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "DELETE, POST, GET, OPTIONS",
"Access-Control-Allow-Headers":
"Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With",
},
timeout: 10000,
};
if (token !== null) {
// config.headers.Authorization = `Bearer ${token}`;
config.baseURL = authUrl;
config.withCredentials = true;
}
let instance = axios.create(config);
instance.interceptors.request.use(
(request) => {
return request;
},
(error) => {
console.log("axios error: ", error);
return Promise.reject(error);
}
);
instance.interceptors.response.use((response) => {
return response;
});
return instance;
};
This code works fine, flexible and can send any kind of request, but when it comes to authentication, there is problem with sending user data: email and password.
const loginHandler = async () => {
const response = await getAxios("/").post("", {
body: JSON.stringify({
email: "example#example.com",
password: "password",
returnSecureToken: true,
}),
});
const outPut = processResponse(response);
console.log(outPut);
}
so as i guess There is problem with this part
{
body: JSON.stringify({
email: "a#a.com",
password: "123456",
returnSecureToken: true,
}),
});
}
if fetch function works this way
fetch(
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPasswordkey=${DATABASE_SECRET}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "example#example.com",
password: "password",
returnSecureToken: true,
}),
}
);
why do axios gives following error:
XMLHttpRequest at ... from origin 'http://localhost:19006' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Please note other get and post request with axios works, and alo authentication works with fetch, only axios shows such an error, please post additional resourses to learn more about firebase rest API and Axios usecases.
This is how error looks like
The baseURL in the axios instance returned by "getAxios" function is https://beauty-wonderland-e913c-default-rtdb.firebaseio.com and not the Auth REST API url. It should be authUrl instead. While in fetch you have hard-coded the URL so the URL is correct for sure.
Edit:
Remove those extraneous headers. You just need content-type as per the docs. I got the same CORS error when I had those.
const config = {
baseURL: baseURL,
headers: {
"Content-Type": "application/json",
},
timeout: 10000,
};

Saving set-cookie value to browser cookies in React

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

How to send body data and headers with axios get request?

I've tried
axios.get(url, {headers:{},data:{}})
But it doesn't work with this.
You should refer to https://github.com/axios/axios#request-config
Check the section for data and header.
As far as I know you can't send body data with GET request. With get you can have only Headers. Just simply change to POST and then you can do something like this :
const bodyParameters = {
key: "value",
};
const config = {
headers: { Authorization: `Bearer ${userToken}` },
};
axios.post("http://localhost:5000/user", bodyParameters, config)
.then((res)=> {
console.log(res)
})
.catch((err) => console.log(err));
};
or if you want to send headers with GET request
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// always executed
});
// data is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', 'DELETE , and 'PATCH'
https://stackoverflow.com/a/54008789
yeah, it's true it doesn't work to send body in Axios get even if it works in the postman or the backend.
You can try this:
const getData = async () => {
try {
const response = await axios.post(`https://jsonplaceholder.typicode.com/posts`, {
method: 'POST',
body: JSON.stringify({
id: id,
title: 'title is here',
body: 'body is here',
userId: 1
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => response.json())
.then(json => console.log(json));
console.warn(response.data);
} catch (error) {
console.warn(error);
}
}
You can send data in a get request by using the config object and the params option of the config object. This is a workaround and it works, but on the server the data sent is available as request.query not as request.body. Based on the example below you would access your params data on your server using request.query.user_id. It should be noted that using this method will also append the params to your request url which could have unintended consequences based on your specific situation. For example, the url for the request below would be sent as example.com?user_id=1234. You can read more about the axios request config here.
axios.get(
'example.com/',
{
params: { user_id: 1234 },
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
},
);

axios.post returns bad request of 400 React Native

I'm getting my token from an API but unfortunately my API is returning 400 bad request. I've already checked my api via Postman and it's working fine there. Kindly let me know solution or any mistake.
async componentWillMount(){
axios.post('http://api.myapiurl.com/token', {
grant_type: 'PASSWORD',
username: 'MY_USERNAME',
password: 'MY_PASSWORD'
}, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).then(response => {
console.log(response.data)
}).catch(err => console.log("api Erorr: ", err.message))
}
error in response below
Request failed with status code 400
- node_modules\axios\lib\core\createError.js:16:24 in createError
- node_modules\axios\lib\core\settle.js:18:6 in settle
- ... 10 more stack frames from framework internals
It is Solved by using QueryString.stringify(). I just pass the body into QueryString.stringify() like below:
axios.post('http://api.apiurl.com/token', QueryString.stringify({
grant_type: 'MY_GRANT_TYPE',
username: 'MY_USERNAME',
password: 'MY_PASSWORD'
}), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
}
}).then(response => {
console.log(response.data)
}).catch(err => console.log("api Erorr: ", err.response))
From what I can see you are sending json data, but your Content-Type header is set to application/x-www-form-urlencoded; charset=UTF-8. if your api is expecting json then it should be application/json.
try using fetch instead, might be some axios bug, you dont need to add any libraries, here is an example:
fetch("http://api.myapiurl.com/token", {
method: "POST", // *GET, POST, PUT, DELETE, etc.
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
grant_type: "PASSWORD",
username: "MY_USERNAME",
password: "MY_PASSWORD"
})
})
.then(res => {
res.json();
})
.then(data => console.log(data)) // ur data is here
.catch(err => console.log("api Erorr: ", err));
First install the package axios from the url https://www.npmjs.com/package/react-native-axios
Then create two service for handling get and post request so that you can reuse them
GetService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const GetService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.get(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
PostService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const PostService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.post(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
Sample code for using get and post services is given below
import { PostService } from './PostService';
import { GetService } from './GetService';
let uploadData = new FormData();
uploadData.append('key1', this.state.value1);
uploadData.append('key2', this.state.value2);
//uploadData.append('uploads', { type: data.mime, uri: data.path, name: "samples" });
let jwtKey = ''; // Authentication key can be added here
PostService(uploadData, 'postUser.php', jwtKey).then((resp) => {
this.setState({ uploading: false });
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
GetService({}, 'getUser.php?uid='+uid, jwtKey).then((resp) => {
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
Reference from one of my another post Post action API with object parameter within the URL
If you have any doubts, feel free to know

Resources