i am finish sessionStore
with MongoStore
every login is being performed correctly and sessions are being written to the database without errors. I am using this package github.com/jfromaniello/passport.socketio to align the passport with socket io but I have already looked for several places about how after login make the treatment of the sessionStorage
so it lists which users with names are online and offline, Could show me a light on this?
app.js
var express = require('express');
var mongoose = require('mongoose');
var path = require('path');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
const MongoStore = require('connect-mongo')(session);
var flash = require('connect-flash');
var logger = require('morgan');
var passport = require('passport');
var passportSetup = require('./passport-setup');
// import routes
var routes = require('./routes');
// setup express app
var app = express();
app.use(logger());
// setup connection with mongodb
mongoose.connect( process.env.MONGODB_URI || "mongodb://smachs:***@d***.mlab.com:****/****-messenger",
(err, db)=> {
if (err) return new Error(err);
console.log('🔐 Conexão estabelecida com banco de dados!');
});
// setup passport from different class
passportSetup();
// set view engine and connection of application
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended:false}));
app.use(cookieParser());
// session storage based in mongodb
var sessionStore = new MongoStore({
url: 'mongodb://smachs:***@d***.mlab.com:****/****-messenger',
ttl: 1 * 24 * 60 * 60, // = 1 days. Default
autoReconnect: true
})
// setup session based in express-session
app.use(session({
secret:"58585858585858",
key: "connect.sid",
resave: false,
saveUninitialized: false,
store: sessionStore
}));
app.use(flash());
// public directory
app.use(express.static(__dirname + '/public'));
// passport staff
app.use(passport.initialize());
app.use(passport.session());
// start routes
app.use(routes);
// start server
var port = process.env.PORT || 3000;
var server = app.listen(port, () => { console.log('🌐 Servidor iniciado em localhost:', port); });;
// setup socket.io and passport.socketio packages
var io = require('socket.io').listen(server);
var passportSocketIo = require("passport.socketio");
// setup session found in express-session
io.use(passportSocketIo.authorize({
cookieParser: cookieParser, // the same middleware you registrer in express
key: 'connect.sid', // the name of the cookie where express/connect stores its session_id
secret: '58585858585858', // the session_secret to parse the cookie
store: sessionStore, // we NEED to use a sessionstore. no memorystore please
success: onAuthorizeSuccess, // *optional* callback on success - read more below
fail: onAuthorizeFail, // *optional* callback on fail/error - read more below
}));
// setup route just for clients authenticate
function ensureAutheticated(req, res, next) {
if (req.isAuthenticated()) next();
else {
req.flash("info", "Você precisa estar logado para visualizar essa página!");
res.redirect('/login');
}
}
// setup current online clients
var User = require('./models/user');
app.use((req, res, next) => {
res.locals.currentUser = req.user;
res.locals.errors = req.flash('error');
res.locals.infos = req.flash('info');
next();
});
// callback from passport.socketio
function onAuthorizeSuccess(data, accept) {
console.log('🗲 Passport-Socket.IO conectado com sucesso');
io.on('connection', function (socket) {
console.log("🗲 Socket.IO-Native conectado com sucesso");
});
// get current user online after authentication
io.on('connection', function (socket) {
// get user details of documents in database
app.get('/user-online', ensureAutheticated, (req, res) => {
User.find()
.sort({ createdAd: 'descending' })
.exec((err, users) => {
if (err) return next(err);
// render response
res.send({
users: users
})
});
});
});
accept();
}
function onAuthorizeFail(data, message, error, accept) {
console.log('failed connection to socket.io:', data, message);
if (error)
accept(new Error(message));
}
user.js
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
const SALT_FACTOR = 10;
var userSchema = mongoose.Schema({
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
createdAt: { type: Date, default: Date.now },
displayName: String,
bio: String
});
userSchema.methods.name = function() { return this.displayName || this.username;}
function noop() { };
userSchema.pre('save', function(done) {
var user = this;
console.log('USER: ' + JSON.stringify( user));
if (!( user.isModified('password'))) return done();
bcrypt.genSalt(SALT_FACTOR, function(err, salt) {
if (err) return done(err);
bcrypt.hash(user.password, salt, noop,
function (err, hashedPassword) {
if (err) return done(err);
user.password = hashedPassword;
done();
});
});
});
userSchema.methods.checkPassword = function(guess, done){
bcrypt.compare(guess, this.password, function(err, isMatch){
done(err,isMatch);
});
};
var User = mongoose.model('User', userSchema);
module.exports = User;
I was trying after login to make an query in a collection to list the users I logged but it is limited to only 1 user and gives me no option to treat this result better, thank you very much for the help they give me!
You can track connection, disconnect, login and logout events to create a list of online users. You can manage online users in RAM or you can use redis for that. Following code snippet may help you achieve your goal -
// Store userIds here
let onlineUsers = [];
io.on('connection', function (socket) {
socket.on('login', (userTokenOrId) => {
// store this to onlineUsers or redis
// Other stuff
});
socket.on('logout', (userTokenOrId) => {
// remove this from onlineUsers or redis
// Other stuff
});
socket.on('disconnect', (userTokenOrId) => {
// remove this from onlineUsers or redis
// Other stuff
});
});
For better use, You can manage one array of objects to store userId and list of socketIds for same and one object to map socketId to userId. This way you can track is one user is online on different browsers/system.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With