react native fetch api error with jwt - reactjs

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.

Related

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;

Getting 401 from fetch in React - Passing sessionId

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.

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.

Cookies are not being accessible in Angular JS

I am working on login application.
For that, I am calling a backend service which is a post call. It returns a cookie. Inside cookie, there is a token. I need that token.
I am trying to get that token, but it is coming null when I try to access in using $cookie.get method.
Can anyone suggest me what could be the possible reason?
Here is the code:
$http({
url:"http://10.11.0.11:4440/j_security_check",
method:"POST",
data:data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(function successCallback(response) {
console.log("Login Success!!");
console.log( "cookie ", response.headers('Set-Cookie') ); //Returning NULL
console.log("cookies"+$cookies.get('JSESSIONID')); //Returning undefined
$location.url("/report");
}, function errorCallback() {
$scope.loginError = "Invalid username/password combination.";
$scope.result = 'error';
console.log('Login failed');
});
Here is the snap of response which I am getting in my browser's network tool:

Nodejs sending external API POST request

i am trying to send a POST request from my angularjs controller to the nodejs server which should then send a full POST request to the external API and this way avoid CORS request as well as make it more secure as i'm sending relatively private data in this POST request.
My angularjs controller function for making the post request to the nodejs server looks like this and it works fine:
var noteData = {
"id":accountNumber,
"notes":[
{
"lId":707414,
"oId":1369944,
"nId":4154191,
"price":23.84
}
]
}
var req = {
method: 'POST',
url: '/note',
data: noteData
}
$http(req).then(function(data){
console.log(data);
});
Now the problem lies in my nodejs server where i just can't seem to figure out how to properly send a POST request with custom headers and pass a JSON data variable..
i've trierd using the nodejs https function since the url i need to access is an https one and not http ,i've also tried the request function with no luck.
I know that the url and data i'm sending is correct since when i plug them into Postman it returns what i expect it to return.
Here are my different attempts on nodejs server:
The data from angularjs request is parsed and retrieved correctly using body-parser
Attempt Using Request:
app.post('/buyNote', function (req, res) {
var options = {
url: 'https://api.lendingclub.com/api/investor/v1/accounts/' + accountNumber + '/trades/buy/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': apiKey
},
data = JSON.stringify(req.body);
};
request(options, function (error, response, body) {
if (!error) {
// Print out the response body
// console.log(body)
console.log(response.statusCode);
res.sendStatus(200);
} else {
console.log(error);
}
})
This returns status code 500 for some reason, it's sending the data wrongly and hence why the server error...
Using https
var options = {
url: 'https://api.lendingclub.com/api/investor/v1/accounts/' + accountNumber + '/trades/buy/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': apiKey
}
};
var data = JSON.stringify(req.body);
var req = https.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
req.write(data);
req.end();
Https attempt return a 301 status for some reasons...
Using the same data, headers and the url in Postman returns a successful response 200 with the data i need...
I don't understand how i can make a simple http request...
Please note: this is my first project working with nodejs and angular, i would know how to implement something like this in php or java easily, but this is boggling me..
So after a lot of messing around and trying different things i have finally found the solution that performs well and does exactly what i need without over complicating things:
Using the module called request-promise is what did the trick. Here's the code that i used for it:
const request = require('request-promise');
const options = {
method: 'POST',
uri: 'https://requestedAPIsource.com/api',
body: req.body,
json: true,
headers: {
'Content-Type': 'application/json',
'Authorization': 'bwejjr33333333333'
}
}
request(options).then(function (response){
res.status(200).json(response);
})
.catch(function (err) {
console.log(err);
})

Resources