Secure authentication with node.js and session.socket.io?

I use the latest versions of node.js and session.socket.io , and this is how I set up the session (please note that I am not using an HTTPS connection, therefore secure: true ):

 app.configure(function() { app.use(cookieParser); app.use(express.session({ signed: true, store: sessionStore, secret: 'SECRET', cookie: { maxAge: 24 * 60 * 60 * 1000, httpOnly: true } })); }); var sessionSockets = new SessionSockets(io, sessionStore, cookieParser); // Later sessionSockets.on('connection', function(error, socket, session) { // session could be used here to detect if user is logged in // eg login: session.name = 'x'; session.save(); // eg checkIfLoggedIn: if (session.name) return true; }); 

Is my code safe / correct or how can I authenticate that the user is really registered? Is it possible / recommended to change the cookie sid on clients (due to its mention here )?

+6
source share
3 answers

I would recommend avoiding re-creating the wheel and using a library like PassportJS . There is a module specifically for using PassportJS with Socket.io here (I have never used this, although I am currently working on a project where I will need it soon). I used PassportJS and it is quite simple. I would recommend this.

+11
source

I know this is a bit outdated, but for future readers, in addition to the approach described by @kentcdodds for parsing cookies and retrieving a session from storage (e.g. my own passport.socketio ), you can also consider a token-based approach.

In this example, I use JSON Web Tokens, which are pretty standard. You must point to the client page token, in this example, imagine the authentication endpoint that returns the JWT:

 var jwt = require('jsonwebtoken'); // other requires app.post('/login', function (req, res) { // TODO: validate the actual user user var profile = { first_name: 'John', last_name: 'Doe', email: ' john@doe.com ', id: 123 }; // we are sending the profile in the token var token = jwt.sign(profile, jwtSecret, { expiresInMinutes: 60*5 }); res.json({token: token}); }); 

Now your socket.io server can be configured as follows:

 var socketioJwt = require('socketio-jwt'); var sio = socketIo.listen(server); sio.set('authorization', socketioJwt.authorize({ secret: jwtSecret, handshake: true })); sio.sockets .on('connection', function (socket) { console.log(socket.handshake.decoded_token.email, 'has joined'); //socket.on('event'); }); 

The malware socket.io-jwt expects a token in the query string, so you only need to connect it when connecting from the client:

 var socket = io.connect('', { query: 'token=' + token }); 

I wrote a more detailed explanation of this method and cookies here .

+13
source

User authentication and session storage using passport

 var express = require('express'), routes = require('./routes'), api = require('./routes/api'), http = require('http'), path = require('path'), mysql = require('mysql'), passport = require('passport'), LocalStrategy = require('passport-local').Strategy; //MySQL var sqlInfo = { host: 'localhost', user: 'root', password: '', database: 'dbname' } global.client = mysql.createConnection(sqlInfo); client.connect(); var app = module.exports = express(); /** * Configuration */ // all environments app.set('port', process.env.PORT || 3000); app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.static(path.join(__dirname, 'public'))); app.use(express.cookieParser("secret")); app.use(express.session({ secret: 'keyboard cat' })); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); passport.use(new LocalStrategy( function(username, password, done) { return check_auth_user(username,password,done); } )); // development only if (app.get('env') === 'development') { app.use(express.errorHandler()); } // production only if (app.get('env') === 'production') { // TODO } /** * routes start--------------------------------------------------------------- */ // home page contain login form app.get('/home', function(reg, res){ //check user session value, is logged in if(req.user) res.render('dash',{ username: req.user['member_id']//req.user array contains serializeUser data }); else res.render('index'); }); app.get('/logout', function(req, res){ req.logout(); res.redirect('/home'); }); //login form submit as post app.post('/login', passport.authenticate('local', { successRedirect: '/dashboard', failureRedirect: '/home' }) ); //to project dashboard app.get('/dash',routes.dash); //to project dashboard app.get('/signup',routes.signup); //to project dashboard app.get('*', routes.index); /** * routes end--------------------------------------------------------------------- */ /** * Start Server */ http.createServer(app).listen(app.get('port'), function () { console.log('Express server listening on port ' + app.get('port')); }); 

Click for more details with an example !

-3
source

Source: https://habr.com/ru/post/945108/


All Articles