How to use express req variables with socket.io - node.js

So what I'm trying to do is when someone loads my site, and gets authenticated by passport, their userId is stored in req.user.id in my app.get('/home', funciton(req, res). Now what I am trying to do in a way is this:
app.get('/home'. function(req, res){
io.on('connection', function(socket){
socket.emit('userId', req.user.id);
});
}
Thats essentially what I'm trying to do, but I know it is very wrong. Now my question is how can I get the req.user.id to the client so I can use it in future interactions with the server.

Looks like you're receiving a GET request and using Express right? You're probably passing the userid in the querystring, so you'll want to use:
req.query.userid
This basically pulls the value assigned to a key in the querystring.
Source: http://expressjs.com/en/api.html#req.query
I would also recommend sending something like ?userid=12345 in the querystring, rather than an object (user.id) in the querystring, as encoding an object will unnecessarily add more complications and not needed.

You can use express session with socket.io
There's a npm module called express-socket.io-session

Related

Express req.session is set and then empty when trying to POST

I have a MERN stack blog app that I'm making as a learning exercise. I'm relatively comfortable on the front end but have limited experience in node. I'm adding authentification after following a couple tutorials to get this far. I'm using passport.js as a framework to make a request to Google, get back an id and save as session info. However, after logging in, req.session is empty when making a post request, even though I can see a cookie in the dev tools.
I'm using bcrypt's hash to obscure the actual id, but that may not be best practice.
in blogAuth.js: req.session is defined.
bcrypt.hash(req.user._id.toString(), saltRounds, function(err, hash) {
req.session.user = hash;
//session is set here.
console.log(req.session); res.redirect(http://localhost:8080/articles/loggedIn);
});
but in api/articles.js: req.session is empty
router.post("/", (req, res, next) => {
const { body } = req;
// session is empty here. Why?
console.log(Session user, ${req.session.user});
console.log(req.session);
I have tried:
Including proxy in the client package.json:
express req.session empty with cookie-session
using withCredentials set to true when sending the POST from the
client:Node + Express + Passport: req.user Undefined
Rearranging the order of middleware: Routes must always come
afterward, but I feel like I'm doing this blindly and it usually results in an error
Here's some of the relevant files:
Server side:
- app.js
- blogAuth.js
- passport.js
- api/articles.js
Client side:
- the POST req
Entire project
I believe this is an issue with ordering. What is a good way to ensure that I order my middleware correctly? Or if the order looks correct, where else could this issue becoming from?
You are trying to use cookie-session as well as express-session. Since both of them will try to control the fate of req.session object, you will end up with empty session always.
Just remove one of them, and your session will be persisted.

node JS express framework sendFile("home.html",{context?})

I'm reading the Express framework docs, making my basic login/redirect page routes.
The following route accepts the submission:
app.post('/',function(req,res){
//console.log("USERNAME: "+req.body.username);
//console.log("PASSWORD: "+req.body.password);
res.redirect('/chat');
});
and this:
app.get('/chat', function(req, res){
res.sendFile(__dirname + '/templates/chat.html');
//console.log("request");
});
takes the user to a new page.
How do I send context? Should I be using res.render()? Neither function seems to contain an option for data like {username:req.body.username}. How should data be passed between routes?
Generally to handle logins with express you'd use something like passport's local strategy, which attaches a user object to the request object (req.user) for you for each route. I don't know that what you're trying will work in a larger context -- you'd need some kind of session-based middleware like express-session at the very least, so you can attach variables per session (I think it gives you req.session). By default, express has the capability to store information for one request/response cycle (res.locals) or for the entire instance of the app (i.e. for all users) (app.locals).
As far as getting data into views, you would use res.render with something like EJS, pug, or another view engine. For example, if in your route, you had something like:
route.get('/', (req, res) => {
res.render('template', { username: 'yourname' })
}
you can refer to that in your ejs template like so:
<h1>Hello, <%= username %>!</h1>
which will get sent back as this:
<h1>Hello, yourname!</h1>
So, to answer your question:
You would use res.render to get variables & data into your views
You don't share data across routes by default except app-level data that applies to all users, which can be set on app.locals
You can use authentication middleware like passport and session middleware like express-session to keep track of user information across routes per session.
Hope this helps! Good luck with express!

Socket.io and request and response objects

I'm quite new on node.js and now I'm learning socket.io.
I'm developing an app step by step so, at this time, I have an app that can login an user, do crud operation in mysql and mongodb and upload files, all these operations are manage with some web pages with HTML and javascript technologies launched directly from restify.
After that I'm tring to add socket functionality to, at this time, simple print who is online.
So, before I have something like:
server.get('/login', function(req, res, next){ ... });
and now I have something like:
socket.on("login", function (req, res, next){ ... });
but, naturally, req and res are undefined!
Are there the same objects into socket.io?
To my understanding, you want to pass values back and forth in your request and response using socket.io.
Yes it is possible to do that and you syntax should be something like this...
Using express.js:
io.on('login', function(req){
client.emit('response event', { some: 'data' });
Note: when using emit you send the data to everyone, you have other methods like .broadcast(), .to(), etc.. for other use cases refer to socket.io github for better understanding
And lastly, inside emit you define the function you want to call on the client side and the data you want to send to the client.

Create session in pure Node js

I know we can create session using Express JS using following,
express.session({ secret: 'secret' });
But I don't want to use any framework. Just only with Node-JS, how can we create session and maintain it?
I do it the following way. I store the session information retrieved from the form into the redis database. You can use something like the one given to store the session information.
var json= JSON.parse(body.toString());
exchange.addUserSession(redisClient,json.userID,json.sessionID,function(err, response){
console.log(response);
res.end(response.toString());
redisClient.quit();
});
And then something like this to actually store the session information in the database.
exports.addUserSession = function (redisClient,userId,sessionId,callback){
//add the user and its session in appsession hash map in redis
redisClient.hset('appsession',sessionId,userId,function(err,response){
callback(err,response);
});
};
Hope it helps
You can check out node-sessions. I have not used it, but after skimming it's home page it looks like you don't need to use any framework.

Node.js Express: passing parameters between client pages

I have a Node.js server. Lets say each client has his name saved on a variable. They switch page and I want each client to mantain their name on a variable.
This would be very easy with a php form, but I can't see how to do it with Node.js
If I do a form like I would do in php, I manage to send the name to the server:
app.post('/game.html', function(req, res){
var user = req.param('name');
console.log(user);
res.redirect('/game.html');
});
But it seems too complicated to then resend it again to each client it's own.
I just started with Node.js, I guess it's a concept error. Is there any easy way to pass a variable from one page in the client to another?
Thanks.
Instead of redirecting to a static file, you have to render the template ( using any engine that ExpressJS supports ):
app.post('/game.html', function(req, res){
var user = req.param('name');
console.log(user);
res.render( 'game.html', { user:user } );
});
( note that .render requires some additonal settings set on app )
Now user variable becomes available in game.html template.
You can use res.render and pass many variables, like that:
res.render('yourPage', {username:username, age:age, phone:phone});

Resources