I have login/signup routes where I save a user to database. Every user has its own page where he can customize eveything. For example user changes his status. Status component makes ajax call to my server, and then my server tries to find a user from the curent session (I do not know how to do that) and then changes his status property in db.
I'm using React, Express, Mongoose.
I thought I coul'd save a user to my req object on /login or /signup route but this doesn't work.
api.get('/login', (req) => {
...getting data from req obj
req.user = user
...doing other things
});
The req object contains data coming in from the http call.
For example if your react app made a GET request to this url
http://localhost/user/123
and you had defined a route in your express app like this
router.get('user/:id', getUser());
then you can access this request object to get the user id in the http url param.
function getUser(req, res) {
let user_id = req.params.id
}
with that user_id you can find a user in the mongodb using mongoose like this.
function getUser(req, res) {
let user_id = req.params.id;
User.findOne({'_id': user_id}, (err, user) => {
if(err) {
return res.json(err);
}
return res.json(user);
});
}
or you can update a user object
function update(req, res) {
let user_id = req.params.id;
let avatar_url = req.body.avtar;
User.findOne({ '_id': user_id }, (err, user) => {
if (err) {
return res.json(err);
}
user.avatar = avatar_url;
user.save((err, user) => {
if(err) {
return res.json(err);
}
return res.json(user);
})
});
}
Recommend you read this to learn the basics.
http://mongoosejs.com/docs/guide.html
https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4
Related
My user session does not persist within the server. I can see within the log that I saved it in my /login route, but when I try to access it from a different route, its "undefined".
My /login route:
app.route("/login")
.post(async (req, res) => {
var username = req.body.username,
password = req.body.password;
console.log('\t we are here')
try {
var user = await User.findOne({ username: username }).exec();
if(!user) {
res.redirect("/login");
}
user.comparePassword(password, (error, match) => {
if(!match) {
console.log('Password Mismatch');
console.log('Ensure redirect to /login');
res.redirect("/login");
}
});
req.session.user = user;
console.log('\t\treq.session:');
console.log(req.session)
var redir = { redirect: "/dashboard" };
return res.json(redir);
} catch (error) {
console.log(error)
}
});
In the above snippet I try to save the session data by req.session.user = user;. Its log appears as:
But now when I try to call the session I just stored, it shows "undefined". This is my /dashboard route & its corresponding log:
app.get("/dashboard", (req, res) => {
console.log(req.session.user_sid);
// console.log(req.cookies.user_sid);
if (req.session.user && req.cookies.user_sid) {
// res.sendFile(__dirname + "/public/dashboard.html");
console.log(req.session);
res.send("send something")
} else {
res.send("go back to /login");
}
});
To my understanding, user authentication is done my checking sessions and cookies, which is why I'm trying to save the session to request.session. I want to the data to persist so that I can use it in all my other routes such as when calling /dashboard api.
Dashboard api will be call by a protected route like when the user is logged in.
I am learning MEAN stack environment and I have a question.
I have a registration page, which registers the user in MongoDB:
// register.component.ts
register(){
this.http.post('http://localhost:3001/register', this.input)
.subscribe(
( next: any) => {
// TO-DO Success event
},
( error: any) => {
// TO-DO Error event
});
}
// app.js
app.post('/register', function(req, res){
db.collection('users').insertOne({
prenom : req.body.prenom,
nom: req.body.nom,
email : req.body.email,
password : req.body.password
})
})
It works pretty well, the problem is that for the connection, I use the _id:
// login.component.ts
login(id: string){
this.http.get('http://localhost:3001/login/' + id).toPromise().then((data: any) => {
this.users = data
})
sessionStorage.setItem('id', id)
}
// app.js
app.get('/login/:id', function(req, res){
db.collection('users').findOne({ email: ObjectId(`${req.params.id}`)}, function(err, user){
if (err) throw err;
if (!user) {
console.log('User not found')
}
else if (user)
{
console.log('Found user: ' + user.prenom)
}
})
})
How to make sure that when the user registers, it returns his _id directly, and like that I can put him in session:
sessionStorage.setItem('id', id)
The db.collection.insertOne() function returns the inserted document, see here. This means you can do a callback or async/await (whichever you prefer) for your insertOne() function and then return the _id by using the Express function res.json(). In your frontend, you'll then get whatever content you put into res.json() as a response. Happy coding! :)
Using MongoDB and Mongoose with Node.JS. I am trying to save too a database and get the newly created ID for the redirect. I understand save() can get the id as a callback. However, I am getting the error: SyntaxError: Invalid destructuring assignment target on the argument req.body in the line
Count.save(err, req.body) => {
The full code:
// #desc Process the count form
// #route POST /session/create
router.post('/session/create', async (req, res) => {
req.body.user = req.user.id
await Count.save(err, req.body) => {
if(err) {
next(err);
}
const itemID = req.body._id;
res.redirect('/new-page' + itemID);
}
});
Count.create(req.body) will create the entry in the database but my understanding is it wont return the id. I don't understand why req.body is a valid argument in one instance and not another?
Figured out the answer. Had to create the instance first, then pass the information in. Below is the working POST request and as a bonus the redirected GET request
// #desc Process the count form
// #route POST /session/create
router.post('/create', (req, res) => {
let session = new Count();
session.name = req.body.name;
session.email = req.body.email;
session.user = req.user.id
session.save(function (err, start) {
if(err)
{console.log(err);
}
else {
console.log(start.id)
}
});
console.log(session.id)
res.redirect('/session/' + session.id)
});
// #desc Continuation of session
// #route GET /session/:id
router.get('/:id', ensureAuth, (req, res) => {
res.render('session/add')
});
I want to update information from by particular id from a user user collection in MongoDB. I am using ExpressJS.
Right now from my code I can only update only login user information. Being a super admin I want to update user's info by ID. What do I need to do here ?
Here now in my code , when super admin logs in he/she can only update his/her own information. I want the super admin to update user's information
router.put('/edit', checkAuth, function (req, res, next) {
if(req.userData.role === 'superadmin') {
const id = req.userData.userId;
User.findOneAndUpdate({ _id: id }, {$set: req.body}, { new: true }, (err, doc) => {
if (err) return res.send(err.message)
if (doc) return res.send(doc);
})
} else {
res.status(401).send(["Not authorized. Only super admin can update details."]);
}
});
How can I update user's information from the collection ?
You need to specify the ID of another user through the request content, in Express this can easily be achieved with a path parameter:
// Example client request: PUT /edit/507f191e810c19729de860ea
router.put('/edit/:userId', checkAuth, function (req, res, next) {
if (req.userData.role === 'superadmin') {
const id = req.params.userId;
User.findOneAndUpdate({ _id: id }, {$set: req.body}, ...);
} else { /* ... */ }
});
If changing the request path (/edit) is not an option for you, you can opt to specify the target user id through the request body instead (you will also need to update the client request to pass that id along with your new user data):
router.put('/edit', checkAuth, function (req, res, next) {
if (req.userData.role === 'superadmin') {
const { id, ...newUserData } = req.body;
User.findOneAndUpdate({ _id: id }, {$set: newUserData}, ...);
} else { /* ... */ }
});
I'm attempting to build a simple CRUD application using express and mongodb. My GET request for all database entries is working and my POST request is working but I can't seem to figure out the problem with my GET request for individual entries.
Server.js GET request:
app.get('/api/:id', function (req, res) {
var id = req.params.id;
db.collection('api').findOne({_id: id}, (err, result) => {
if (err){
res.sendStatus(404);
return console.log(err);
}
res.redirect('/');
return console.log(result);
});
});
When I type 'url/api/593555074696601afa192d7f' which is an ID I know exists the console.log is returning null, I'm not sure if I'm doing something wrong?
You should pass ObjectID instance in the query.
let ObjectID = require("mongodb").ObjectID;
app.get('/api/:id', function (req, res) {
var id = req.params.id;
db.collection('api').findOne({_id: ObjectID(id)}, (err, result) => {
if (err){
res.sendStatus(404);
return console.log(err);
}
res.redirect('/');
return console.log(result);
});
});
Give Mongoose a try. It might be of help if your models get complex.