Reputation: 560
I'm using the latest versions of node.js and session.socket.io and this is how I set the session (please note that I'm not using a HTTPS connection so no 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
// e.g. login: session.name = 'x'; session.save();
// e.g. checkIfLoggedIn: if (session.name) return true;
});
Is my code safe/correct or how I could authenticate that a user is really logged in?
Is it possible/recommended to change the sid
of the cookie on the clients (due it's mentioned here)?
Upvotes: 9
Views: 23199
Reputation: 14156
I know this is bit old, but for future readers in addition to the approach described by @kentcdodds of parsing cookie and retrieving the session from the storage (eg. my own passport.socketio module) you might also consider a token based approach.
In this example I use JSON Web Tokens which are pretty standard. You have to give to the client page the token, in this example imagine an authentication endpoint that returns 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: '[email protected]',
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 socket.io-jwt middleware expects the token in a query string, so from the client you only have to attach it when connecting:
var socket = io.connect('', {
query: 'token=' + token
});
I wrote a more detailed explanation about this method and cookies here.
Upvotes: 27
Reputation: 766
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 example!.
Upvotes: -3
Reputation: 29021
I would recommend avoiding re-inventing the wheel and using a library such as PassportJS. There is a module specifically for using PassportJS with Socket.io here (I've never used this though I'm currently working on a project where I'll need it soon). I have used PassportJS and it's quite simple. I would recommend this.
Upvotes: 15