Getting 401 from fetch in React - Passing sessionId - reactjs

I'm building react app, first screen is a login form that is calling a GET rest api resource in other host (8080)(CORS extension on chrome was installed to overcome CORS issue).
After logging in successfully, trying to perform another GET fetch but this time am getting 401!
Tried setting the credentials: 'same-origin' or credentials: 'include' (in both calls, login and second one) but it didn't help!
fetch('http://<some host>:8080/WebServices/api/SessionManager/login?userName='
+ this.state.userName + '&password=' + this.state.password,
{
//credentials: "include",
//mode: "no-cors"
})
.then(
(response) => {
if (response.status < 200 || response.status > 300) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
this.state.showError = true;
this.state.errorMessage = 'Please enter a valid credentials.';
return;
} else {
localStorage.setItem('session', response);
console.log("Response ======>", response);
window.location.href = '/main';
}
}
)
.catch((error) => {
console.error(error);
});
second call:
function getSession(){
return localStorage.getItem('session').then(response => JSON.parse(response))
}
function getProjectDetails(){
let params = getSession();
let headers = new Headers();
fetch('http://<host>:8080/WebServices/api/ProjectManager/getProjectDetails?userSessionId=', params
// {
// //credentials: "include",
// //credentials: "same-origin",
// //crossdomain: true,
// //mode: 'no-cors',
// //headers: headers
// }
)
//.then(res => res.json())
.then((data) => {
this.setState({ projectsDetails: data })
console.log(data);
})
.catch(console.log);
}
class App extends Component {
Is there a way to get the session from browser cookies and set it into the header or parameters of fetch? how can I solve it?

If I understand it right you are asking how to store and retrieve stored values from the cookies.
First you need to store the data you get from the first fetch with, be aware that must convert he json response to string with JSON.stringify.
localStorage.setItem('session', JSON.stringify(response));
An then you can retrieve it with:
localStorage.getItem('session');
LocalStorage has to be stored as json, and decode it after getItem().
So in order to add the session params to the second fetch you can do as follows:
function getSession(){
return JSON.parse(localStorage.getItem('session'))
}
// second fetch,
function secondFetch(){
var params = getSession();
// in var params you have the data stored so now you can do the second fetch
}
I hope I've been of help to you, anything don't hesitate to ask.

Related

Getting bad request from server (Spring boot) when using axios request

I'm currently stuck sending a request to my server and can not get a response. I have tried it on postman and it runs completely fine. However, when I try to put it on react, the back-end always response with a bad request.
Here is my code for the back-end
#GetMapping(value = "/searchPatient")
public ResponseEntity<?> searchPatients(#RequestParam String id_num,
#RequestParam String name) {
List<PatientForSearchDto> patientForSearchDtos = patientService.viewSearchedPatient(id_num, name);
return ResponseEntity.status(HttpStatus.OK).body(
new ResponseObject("ok", "Success", patientForSearchDtos)
);
}
Here is my code for Front end (react)
async function sendRequest () {
const formData = new FormData();
formData.append('id_num', id_num);
formData.append('name', name);
console.log(formData)
console.log(formData.get('name'))
console.log(formData.get('id_num'))
const config = {
method: 'get',
url: 'http://localhost:8080/api/searchPatient',
// headers : {
// 'Content-Type': 'from-data'
// },
data : formData
};
await axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
setPatientList(response.data.data.object)
})
.catch(function (error) {
console.log(error);
});
}
Here is what I get when sending request via postman
enter image description here
Here is when sending request using react
enter image description here
From the Axios docs about Request Config data param:
// data is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', 'DELETE , and
'PATCH'
So, data with GET method is not supported.
Can't you use params instead?

REACT + Typescript, making API with Axios. headers makes type error

I'm so Newbie in Programming.
I'm using Django as backend, React+Typescript as frontend.
I'm using Axios to make JWT login function. but stuck in the middle.
Because headers/Authorization makes type error.
as above Authorization does not work.
showing this error.
Can anyone help me out of this situation?
Try to remove the null in your condition. Replace it with either undefined or a empty string ""
Authorization: localStorage.getItem("access_token") ? "JWT" + localStorage.getItem("access_token") : ""
const axiosbase = axios.create({
baseURL: 'Your Base URL',
timeout: 5000,
transformRequest: [(data, headers) => {
return data;
}]
});
//default headers
var token = 'Your JWT';
axiosbase.defaults.headers["Authorization"] = 'Bearer ' + token;
axiosbase.defaults.headers["Accept"] = 'application/json, text/plain, */*';
axiosbase.defaults.headers["Content-Type"] = 'application/json';
// Add a request interceptor
axiosbase.interceptors.request.use((config) => {
return config;
}, (error) => {
// Do something with request error
console.log('Error occured while request');
return Promise.reject(error);
});
// Add a response interceptor
axiosbase.interceptors.response.use(
(response) => {
// Do something with response data
//console.log('Response was received');
return response;
},
);
export default axiosbase;

ReactJS catch HTTP error

I have the next problem: I made authentication using Spring Security and after entering incorrect data, it(java server) sends HTTP 401 status code.Image
I can't catch this exception. I'm using fetch API, but catch doesn't work and response.status too. How can I solve this?
login = (event) => {
event.preventDefault();
var data = {username: this.refs.username.value, password: this.refs.password.value};
var that = this;
fetch('http://localhost:8080/login',{
method: 'POST',
mode: "no-cors",
body: JSON.stringify(data),
headers:{
'Content-Type': 'application/json'
}
}).then( (response) => {
console.log(response);
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
} else {
console.log('Yeeee man, you can login');
this.props.history.push('/');
}
}).catch(error => console.log('Error ' + error));
}
Check the object first console.log(response.status) or try use response.data.status
Sometimes the response is placed inside the object data
I found the solution. The problem was in mode: 'no-cors'. It means that I can send the request but I will not be able to read the response... So I needed to enable cors in java.

PUT Request with AngularJS and Express

When I'm performing a put request and console.log(response) of the request I only get a JSON Object like {"res":1} instead of getting the whole json object with its changes in order to update him in a database.
Controller :
$scope.doneEdit = function (components) {
console.log(components);
components.editing = false;
if (components.editing === false) {
$http.put('/propt/' + components._id).then(function (response) {
console.log(response.data);
});
}
}
Express
app.put('/propt/:id', function(req,res) {
console.log(req.body);
testDb.update({_id:req.params.id}, req.body, {}, function(err, numReplaced){
res.statusCode = 200;
res.send(req.body);
})
})
You should pass the data you want to send as a second parameter to put method:
$http.put('/propt/' + components._id, {someValue:components.someValue})
You can find the documentation here: https://docs.angularjs.org/api/ng/service/$http#put

react native fetch api error with jwt

I am trying to implement Jsonwebtoken in my react native app. I followed the video tutorial on their official site and it worked fine. However, I kept getting errors "UnauthorizedError: No authorization token was found" every time I try to make api calls. The api calls all work as expected except I would still get errors like that. I tried the same api calls in postman, they don't give me errors. I found it's possibly because I didn't pass the token back after the api calls?
Here is where I initiate the express-jwt
var expressJWT = require('express-jwt')
app.use(expressJWT({secret: 'I like different tastes'}).unless({path:['/api/users/login', '/api/users/register', '/api/users/register/facebook']}))
Here is where I log in and create and pass back a jwt to my client side
login: function(req,res){
if (req.body.purpose == 'login'){
User.findOne({'localUser.email': req.body.email,}, function(err, user){
if (err){
console.log(err)
res.status(500).json('error')
}
else if(user == null){
res.status(404).json('not found');
}
else{
if (passwordHash.compareSync(req.body.password, user.localUser.password)){
var myToken = jwt.sign({username: user.localUser.name}, 'I like different tastes')
var tmpUser = user.toJSON()
tmpUser.token = myToken
res.status(200).json(tmpUser);
}
else{
res.status(401).json('wrong credentials')
}
}
})
}
else{
res.status(400).json('You are hacked bro')
}
And this is an example of the api calls I make after I log in.
fetchPost() {
var _this = this
return fetch(uri.network.uri + '/api/posts/fetch', {
method: 'POST',
headers: {
'Authorization': 'Bearer '+this.props.activeUser.token,
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
purpose: 'fetchPost',
latitude: this.state.currentRegion.latitude,
longitude: this.state.currentRegion.longitude,
maxSearch: MAX_SEARCH
})
})
.then((response) => {
if (response.status != 200){
Alert.alert(
'Sorry',
'Unexpected errors!'
);
return
}
else{
return response.json();
}
})
.then((responseJson)=>{
console.log(responseJson)
})
.catch((error) => {
console.error(error);
});
}
this.props.activeUser.token is the token I passed back from the second function in server side
it worked fine and I get the data I want. I also believe I was passing the right token since I tried passing a random token which resulted in incorrect response.
The problem is that I would get UnauthorizedError: No authorization token was found.

Resources