I am trying to simply set the cookie for the JSON Web Token during authentication in my Node.js and Express web application.
Since I cannot do res.redirect after using res.cookie(), how can I achieve this?
router.post('/', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (!user) { return res.redirect('/auth'); }
var theToken = jwt.encode({ id : user.id }, req.app.get('appSecret'));
res.cookie(theToken);
return res.redirect('/profile/' + username);
})(req, res, next);
});
Am I approaching this problem correctly? I cannot find much of anything on how people are setting their JSON Web Tokens once they have created them.
It seems that res.redirect works with setting the cookies, despite what some other SO answers state. Hopefully this helps someone else.
Related
I am currently using app.get and app.post for input and output from my database. This works perfectly fine, but when I go to the /login page for my web application, I am able to see all of the data for all of the players in a large array. I tried this on multiple computers, and it seems that anyone can view it. Is there any way to make app.get and app.post pages unreachable?
My code snippet:
app.use(express.json());
app.use(express.urlencoded());
app.post('/login', (req, res) => {
var query = { username: req.body.username };
dbo.collection("data").find(query).toArray(function(err, result) {
if(result.length == 0){
var myobj = { username: req.body.username, password: req.body.password };
dbo.collection("data").insertOne(myobj, function(err, res) {});
}
res.send(result);
});
});
app.get('/login', (req, res) => {
dbo.collection("data").find({}).toArray(function(err, result) {
if (err) throw err;
res.send(result);
});
});
I am using mongodb's serverless instance, and node.js to run the code.
On the /login page(example.com/login):
The passwords were changed for privacy sake.
With everyone's comments, I was able to figure out how to fix it!
The way to fix the problem, is to use app.post() functions to transfer data from the index.html file to the index.js file. This allows everything to be done behind the scenes. With this information, I was able to only res.send() a boolean instead of the entire array. This made it so that the page only showed "true" or "false" instead of everyone's data. Furthermore, I used bcrypt to encrypt passwords, so even if hackers could see the data, they could not hack anyone.
so i have a chat app that i am working on here and i am trying to make it to where a user can type in like https://niknet.ddns.net/room/randomroomUID and it will join them to that room if they are logged in (i use password for handling login and signup) my code looks like this on my routes.js (in case you dont know it's the js that handles all my express stuff)
i tried this
app.get('/room/:roomUid', isLoggedIn, function(req, res) {
console.log(req.params.roomUid)
console.log(req.user)
res.cookie('uid',req.user.uid, { maxAge: 999999999999999999999});
var username = req.user.displayName;
app.post( 'apolloMainchat',{ roomUid:req.params.roomUid , username});
});
but im not sure how to pass the information across to the express code that handles when users /apolloMainchat
typically a user can get to /apolloMainchat like this
app.get('/apolloMainchat', isLoggedIn, function(req, res) {
console.log(req.user)
res.cookie('uid',req.user.uid, { maxAge: 999999999999999999999});
var username = req.user.displayName;
res.render('apolloMainchat.ejs', username);
console.log(req.user.displayName)
});
any one know how to help me?
You will want to pass this by redirecting the client to a new endpoint and then reading those parameters from the query as Renato Gama said in the comments.
Your code will then become something like this.
app.get('/room/:roomUid', isLoggedIn, function(req, res) {
res.cookie('uid',req.user.uid, { maxAge: 999999999999999999999});
app.redirect('apolloMainchat?roomUid=' + req.params.roomUid);
});
app.get('/apolloMainchat', function(req, res, next) {
console.log(req.params.roomUid);
});
You're just using a HTTP redirect to pass them to the new endpoint and attaching the data as a query parameter as you would if they requested it directly. It's not quite clear what you're trying to achieve, but this should do what you've described.
I am creating a user management system - However I am current finding myself checking the user type on a per router bases.
router.get('/admin/settings', (req, res) => {
if(admin) {
//Proceed.
}
}
router.get('/admin/users', (req, res) => {
if(admin) {
//Proceed.
}
}
Is there a better way of doing this? Can't I just set a route like this?
router.get('/admin*', (req, res) => {
if(!admin) {
res.status(404).send('Not found')
}
}
(I have tried and not succeeded, feels like it clashes with other routes)
Also, on a similar note. How Am I supposed to handle denying a user access to a script? Do I send a 404 or 403?
You can use an Express middleware function:
router.use(function(req, res, next) {
if(admin) {
return next();
}
// We fail closed
return res.status(403).send('Forbidden');
});
// This won't get called if the middleware doesn't call next()
router.get('/admin/settings', (req, res) => {
// Do stuff
}
Here, we call next() only if the user is an admin, which allows the call to continue. Any routes added after this middleware will be protected.
Also, on a similar note. How Am I supposed to handle denying a user access to a script?
A 403 is the appropriate code here, though a 404 can also be used if you wish to hide the route from unauthorized clients. I would suggest reading up on what each code is designed for.
I am working with a single app application framework called reactjs, the issue I encountered is setting httpOnly cookies, as they can not be set / read from a client side I needed to figure out a way how to use express for this.
One idea I came up with is to make a post request to a route like /cookie:data where data is value of token that needs to be stored in a cookie, so:
app.post('/cookie:data', function(req, res) {
// Set cookie here
res.send(200)
})
Issue I am hesitant about is that token contains unique user identifier that is used to secure api, and I am not sure if I am or am not exposing this by setting up a cookie this way.
Alternatively instead of using :data it would be beneficial to figure out how I can grab data (json object) from the post request
EDIT:
One issue I can think of is that anyone can post to this route and set different cookies? what would be a way of securing it?
EDIT 2:
This is the express setup I use to proxy api calls (only relevant for clarifying comments)
app.use('/api', function (req, res) {
let url = config.API_HOST + req.url
req.pipe(request(url)).pipe(res)
})
Say that you want to proxy all requests starting with /api to a third-party, except /api/users, which you want to perform 'manually' because it returns a token you need:
app.post('/api/users', function(req, res) {
let url = config.API_HOST + req.url;
let apiRequest = request.post(url, function(err, response, body) {
// Responses are just examples, you should tailor them to your situation
if (err) {
return res.sendStatus(500);
} else if (response.statusCode !== 200) {
return res.sendStatus(response.statusCode);
} else {
res.cookie('token', body).send('OK');
}
});
req.pipe(apiRequest);
})
app.use('/api', function (req, res) {
let url = config.API_HOST + req.url
req.pipe(request(url)).pipe(res)
})
Sorry for my bad English!
I build an app using MEAN Stack (MongoDB + Express.js + Angular.js + Node.js) and authentication using passport.js and JWT (jsonwebtoken and express-jwt).
What i want to do?
The login and registration routes render html, using nunjucks, and if it goes success we render index.html file, placing in public directory.
P.S.: is this a correct method?
What is my question?
Can anyone tell me, the technology to do this?
My code (based on https://thinkster.io/mean-stack-tutorial):
app.get('/', function(req,res){
if (!req.user)
res.redirect('/about')
else
res.render('index')
});
app.get('/login',function(req, res) {
res.render('auth/login', {
title: 'Login'
});
});
app.post('/', function(req, res, next) {
if (!req.body.login || !req.body.password) {
return res.status(400).json({ message: 'Please fill out all fields' });
}
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (user) { return res.json({ token: user.generateJWT()});
/*generateJWT form user model code returns jwt.sign({}) using jsonwebtoken:
var jwt = require('jsonwebtoken');
*/
} else { return res.status(401).json(info);}
})(req, res, next);
});
In this code we return generated token, if login is success. What should i do to render index.html and what could i do with generated token?
Sorry for this dummy questions, i'm still learning jwt. Thank's
Node is a Server Side Language. Since you are using MEAN stack, generally,
you need to create APIs in node and pass datas to client side Angular.
So to answer your question- To render html, your function for login needs to return something to client, using callbacks, and Angular will render your html pages.
What you need to do with the generated token is that from next time any requests to server without the token will/should generate error.
Else anyone can call your node APIs and and desired results. This is extremely necessary atleast for GET methods.