I'm trying to redirect the user after the signup has been validated. See the code below, it never worked with everything i have tried. I also tried on the front end part with
<Redirect=to"/login" />
it wasn't a success either. I'm trying to redirect to : http://localhost:3000/login, the backend is currently on port 5000.
I also that those errors coming in the console :
Access to XMLHttpRequest at 'http://localhost:3000/login' (redirected from 'http://localhost:5000/users/signup') from origin 'http://localhost:3000' 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.
GET http://localhost:3000/login net::ERR_FAILED
createError.js:16 Uncaught (in promise) Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:99)
My first thought was that the header is not set, but it is in my app.js
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content, Accept, Content-Type, Authorization"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, PATCH, OPTIONS"
);
next();
});
Thanks in advance
exports.signup = (req, res) => {
bcrypt.hash(req.body.password, 10).then((hash) => {
const user = {
lastName: req.body.lastName,
firstName: req.body.firstName,
email: req.body.email,
password: hash,
};
User.create(user)
.then(() => {
res.redirect(301, 'http://localhost:3000/login');
})
.catch((error) => res.status(500).json({ message: "Impossible de créer l'utilisateur. " + error }));
});
};
res.status(200).redirect('login');
(EDIT) This will return 200 and redirect the user from the backend.
This is my solution from the front-end, if you'd like it.
On the frontend, you could redirect to your desired location using window.location.replace('/login') after the express returns a value.
What I mean by this is after you've validated the user on your Express API, return 200 via res.status(200).send() to let your front end know that this user is allowed to be redirected.
An example with jQuery:
Front-End
<script>
$.get('http://localhost:3000/login', function(data, status, jqXHR) {
if (status === 200) {
window.location.replace('redirect-location.html')
} else {
// What to do if the status isn't 200
}
})
</script>
Back-End:
app.get('/login', (res, req, err) => {
// Validate
const result = validatefunction() // true if login matches, false otherwise
if (result) {
res.status(200).send()
} else if (!result) {
res.status(400).send()
} else {
res.status(500).send()
}
})
Hope I've helped.
Related
I am new to node.js. I need to use Json Web Tokens to authenticate my login requests.
In Postman and in the devtools, POST requests are working well : a new jwt is created for each request (seePOSTMAN, see DEVTOOLS
But, my authorization headers does not contain any jwt...
I got something like "Authorization : Bearer " (see AUTHORIZATION).
Here is my code :
**user.js/controllers
**
exports.login = (req, res, next) => {
User.findOne({ email: req.body.email })
.then(user => {
if(!user) {
return res.status(401).json({ message: 'Utilisateur non trouvé !'});
}
bcrypt.compare(req.body.password, user.password)
.then(valid => {
if(!valid) {
return res.status(401).json({ message: 'Mot de passe incorrect !'});
}
res.status(200).json({
userId: user._id,
token: jwt.sign(
{ userId: user._id},
'RANDOM_TOKEN_SECRET',
{ expiresIn: '24h' }
)
});
})
.catch(error => res.status(500).json({ error }));
})
.catch(error => res.status(500).json({ error }));
};
**app.js
**
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content, Accept, Content-Type, Authorization');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
next();
});
How can I fix that ?
I'm running out of leads or solutions...
Thanks !
I am expecting to see the jwt appears just next to "Authorization: Bearer".
I have a React application using axios as HTTP library, express server that uses http-proxy-middleware package and API express server that contains APIs.
React application should communicate with API server through proxy authentication server like this:
Within my React application I created this test method:
testReq(){
axios.get('http://localhost:5000/applicationData/checkMe', {
withCredentials: true,
headers: {
'x-access-token': '...'
}
})
.then(response => console.log(response.status))
.catch(e => console.log(e))
}
This is how my proxy method looks like:
server.use('/applicationData', authenticate, proxy({
target: 'http://localhost:4000',
changeOrigin: false,
onProxyReq(proxyReq, req) {
// proxyReq.setHeader('x-access-identity-email', req.decodedToken.email)
},
}))
and this is authenticate middleware function used above:
module.exports = (req, res, next) => {
const token = req.headers['x-access-token']
console.log('token', token)
if (token) {
verifyToken(token, global.config.secret).then((verificationResponse) => {
const { decoded, message } = verificationResponse
if (!decoded) return res.status(401).json({ message })
req.decoded = decoded
return next()
})
.catch((err) => {
console.error(err)
res.status(500).json({ message: 'Internal error' })
})
} else return res.status(401).json({ message: 'Missing authentication token' })
}
I enabled CORS on both API and Proxy servers like this:
server.all('/*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, x-access-token')
res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
res.header('Access-Control-Allow-Credentials', 'true')
next()
})
The problem is that I get this response when request is sent:
I assume it's due to authentication middleware trying to access x-access-token header from OPTIONS request which doesn't exist and therefore returns 401. If I remove authentication middleware from proxy method then requests go through.
How do I make x-access-token present in OPTIONS requests? Or else, what is the proper way to handle this situation?
in facebook not allowing to paste code not sure, why, so pasting here:
in your middleware missing is (for options part as you have commented):
if (req.method == 'OPTIONS') {
res.send(200);
}
else {
next();
}
for error part, as you have said authentication triggering before cors part, so you may have to set that code before authentication (security part I am not much sure)
I think the line:
res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, x-access-token')
should be:
res.header('Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, x-access-token')
I recently created a server and deployed it to Heroku. It works fine in Postman and when testing out basic GET requests. But whenever I try to make POST request to it via Axios in my client, I am met with this error.
In my back-end server, I enabled cors so that it could make cross-domain requests. Here, on lines 67 and 69, I set up cors before declaring my routes (click here to see the full 'app.js' file on my github.)
My register router works fine in Postman, and its response time is below 30 seconds, at 1877 milliseconds.
Interestingly, when I make a conditional GET requests to my API in my client, it works. (The lines of code where I make aforementioned GET request are on line 222-258 here)
In my client, the problem arises whenever I want to make a POST request in my client. Here is network response I get in the image below.
If I go to the response tab, it shows my POST request timing out at 30.1 seconds, despite the fact that the same API request was finished in 1.8 seconds in Postman.
Here is the code in particular where I am making the POST request in my index_actions.js file.
import axios from 'axios'
export function register(fields) {
console.log('below are the fields');
console.log(fields);
return function action(dispatch) {
let objArrSkills = Object.keys(fields.form_skills);
let skillsArr = objArrSkills.map(function (value) {
if (fields.form_skills[value] === true && fields.form_skills[value] !== undefined) {
return value;
}
});
let objArrArts = Object.keys(fields.form_arts);
let artsArr = objArrArts.map(function (value) {
if (fields.form_arts[value] === true && fields.form_arts[value] !== undefined) {
return value;
}
});
console.log('artsArr is...' + artsArr);
console.log('skillsArs is...' + skillsArr);
const request = axios({
method: 'post',
url: "https://jammr-backend.herokuapp.com/register",
data: {
firstName: fields.form_first_name,
lastName: fields.form_last_name,
email: fields.form_email,
password: fields.form_password,
skills: skillsArr,
iWantToMake: artsArr,
street: fields.form_address,
city: fields.form_city,
provinceState: fields.form_province,
gender: fields.form_gender,
imLookingFor: ['Acting', 'Drawing', 'Music', 'Writing', 'Programming', 'Videography']
},
headers: {
'Access-Control-Allow-Origin': '*'
}
});
return request.then(response => {
console.log('axios call ran! Below is response....');
console.log(response);
dispatch({
type: 'REGISTER',
payload: {
myId: response.data,
fields: fields,
skills: skillsArr,
iWantToMake: artsArr
}
})
},
err => {
if (err) throw err;
})
}
};
Everything works fine right up until I make the Axios to the /register route. The files pertaining to this issue are here and here.
UPDATE: I went into my app.js file to change the Cors configuration.I commented out app.use(cors()); and app.options('*', cors()); and replaced it with this.
/// x-auth is a custom-header in my server-side code
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,x-auth,Accept,content-type,application/json');
next();
});
/// After this line, I declare my routes.
However, now I am getting this error Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.
I am trying to get my React-Redux app to communicate to my deployed Heroku API via Axios.
When I try to make a POST request to my Heroku server via Axios I get this error message in my console in the Chrome developer tools:
As you can see in the screencap, I am getting "No 'Access-Control-Allow-Origin' header is present on the requested resource." as well as error status code of 503.
And something I find rather odd is that my /register request is being fired twice. Is that normal?
Here is the configuration in my app.js file in my backend code to enable cross domain requests:
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS');
res.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Origin,X-Auth,X-Requested-With,Content-Type,Accept,content-type,application/json,x-auth,Access-Control-Request-Method,Access-Control-Request-Headers");
next();
});
And here is the Axios code that makes the API call to the server in my front-end:
import axios from 'axios'
export function register(fields) {
console.log('below are the fields');
console.log(fields);
return function action(dispatch) {
let objArrSkills = Object.keys(fields.form_skills);
let skillsArr = objArrSkills.map(function (value) {
if (fields.form_skills[value] === true && fields.form_skills[value] !== undefined) {
return value;
}
});
let objArrArts = Object.keys(fields.form_arts);
let artsArr = objArrArts.map(function (value) {
if (fields.form_arts[value] === true && fields.form_arts[value] !== undefined) {
return value;
}
});
console.log('artsArr is...' + artsArr);
console.log('skillsArs is...' + skillsArr);
const request = axios({
method: 'post',
url: "https://jammr-backend.herokuapp.com/register",
data: {
firstName: fields.form_first_name,
lastName: fields.form_last_name,
email: fields.form_email,
password: fields.form_password,
skills: skillsArr,
iWantToMake: artsArr,
street: fields.form_address,
city: fields.form_city,
provinceState: fields.form_province,
gender: fields.form_gender,
imLookingFor: ['Acting', 'Drawing', 'Music', 'Writing', 'Programming', 'Videography']
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': "Access-Control-Allow-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Origin,X-Auth,X-Requested-With,Content-Type,Accept,content-type,application/json,x-auth,Access-Control-Request-Method,Access-Control-Request-Headers",
'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
}
});
return request.then(response => {
console.log('axios call ran! Below is response....');
console.log(response);
dispatch({
type: 'REGISTER',
payload: {
myId: response.data,
fields: fields,
skills: skillsArr,
iWantToMake: artsArr
}
})
},
err => {
if (err) throw err;
})
}
};
Is there anything wrong with my code? Here is my front-end and back-end code on Github.
And in case it's relevant, my backend is deployed on Heroku. Also, I did try using the cors npm package, but it didn't work.
I would be willing to bet you are getting the 503 from the heroku stack because of some issue with your backend. (A timeout perhaps?) Obviously, the Heroku stack is not going to add the cross origin headers which is why you are seeing the cross origin errors in the JS console. Can you perhaps post your server logs?
SOLVED, see my answer below
My server runs on localhost:3000
I develop on localhost:4200
I am creating something and trying to post it on an Amazon API
Angular side code:
sendSomething(something) {
const body = JSON.stringify(something);
// const headers = new Headers({'Content-Type': 'application/json'});
const headers = new Headers({'Access-Control-Allow-Origin': '*'});
return this.http.post('http://Amazon-API:port/send', body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => {
this.error.handleError(error.json());
return Observable.throw(error.json());
});
}
Server side:
//////////////app.js//////////////
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", '*'); //<-- you can change this with a specific url like http://localhost:4200
// res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
next();
});
app.use('http://Amazon-API:port', engineRoutes);
//////////////routes/engine.js//////////////
router.post('/send', engine_controller.send_something);
//////////////controllers/engine.controller.js//////////////
exports.send_something = function (req, res, next) {
const somethingID = req.body.something;
Something.findById(somethingID, function(err, something) {
if (err) {
res.status(404).json({
title: 'Something not found',
error: {message: 'Something went wrong'}
});
}
console.log(something);
if (something) {
res.status(200).json({
message: 'Something successfully sent',
something: something
});
}
})
};
I have tried posting to that API with cors, without cors and with the res.headers appended, and every other variation I could think of
I still get this error which I've seen so common around here, but still, their solutions don't seem to work for me. Still getting this error...
Failed to load http://Amazon-API:port/send: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403.
That's from NETWORK tab:
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:he-IL,he;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers:access-control-allow-origin
Access-Control-Request-Method:POST
Connection:keep-alive
Host:Amazon-API:port
Origin:http://localhost:4200
Any kind of help would be so much appreciated
I see you added this code but I can't post comment yet, you may try to add this code before other routes
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With,
Content-Type, Accept');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PATCH, DELETE,
OPTIONS');
next();
});
Solved,
What I did was routing back to the server on the front:
sendSomething(something) {
const body = JSON.stringify(something);
const headers = new Headers({'Content-Type': 'application/json'});
return this.http.post('http://localhost:3000/api/somethings/send-something', body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => {
this.error.handleError(error.json());
return Observable.throw(error.json());
});
}
And then accepting this route as it is on the back:
//////////////app.js//////////////////
app.use('/api/somethings/send-something', engineRoutes);
/////////////routes/engine.js/////////
router.post('/', engine_controller.send_something);
And most importantly, in the controller itself I used the newly downloaded request lib to send my json data to my external API:
////////////controlllers/engine.controller.js////////////
const request = require('request');
exports.send_something = function (req, res, next) {
const SomethingID = req.body.something;
Something.findById(SomethingID, function(err, something) {
if (err) {
res.status(404).json({
title: 'Something not found',
error: {message: 'Something went wrong'}
});
}
request({
url: app.get('amazon-API:port/method'),
method: "POST",
json: something
}, function (error, response, body) {
// console.log(error) <--- returns null or error
// console.log(response.statusCode <--- returns 200 / 403 / w.e
// console.log(body) <--- returns response pure html
res.status(200).json({
message: 'Something successfully sent',
response: body,
status: response.statusCode
});
});
})
};
Now as a response I'm getting what the server which I posted to sends me back, which is exactly what I need.
Ultimately I figured my way thanks to many other questions posted here
So thank you SOF once again!