9

我正在使用最新版本的 node.js 和session.socket.io,这就是我设置会话的方式(请注意,我没有使用 HTTPS 连接,所以没有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;
});

我的代码是否安全/正确,或者我如何验证用户是否真正登录?是否可以/建议更改sid客户端上的 cookie(因为这里提到了)?

4

3 回答 3

27

我知道这有点老了,但是对于未来的读者来说,除了@kentcdodds 描述的解析 cookie 和从存储中检索会话的方法(例如我自己的passport.socketio模块)之外,您还可以考虑基于令牌的方法。

在这个例子中,我使用了非常标准的 JSON Web Tokens。您必须向客户端页面提供令牌,在此示例中,想象一个返回 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});
});

现在,您的 socket.io 服务器可以配置如下:

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');
  });

socket.io-jwt 中间件需要查询字符串中的令牌,因此从客户端您只需在连接时附加它:

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

我在这里写了关于这个方法和cookies的更详细的解释。

于 2014-01-16T15:05:31.193 回答
15

我建议避免重新发明轮子并使用诸如PassportJS之类的库。这里有一个专门用于将 PassportJS 与 Socket.io 结合使用的模块(尽管我目前正在开发一个很快需要它的项目,但我从未使用过它)。我使用过 PassportJS,它非常简单。我会推荐这个。

于 2013-07-09T20:18:10.517 回答
-3

使用 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'));
});

单击以获取更多详细信息,例如!。

于 2013-10-14T08:49:58.720 回答