Session Node.js + Passport.js + Redis,按user.id存储会话

时间:2016-01-29 03:41:29

标签: javascript node.js redis passport.js middleware

当为用户创建用户登录会话时,如果他要去另一台计算机并登录,则会为他的帐户创建第二个会话。我想这样做,以便用户不能有一个以上的有效会话。无论如何用user.steamId在redis中存储会话,以便他的第一个会话变得无效?

任何帮助都会非常感谢!

app.js

    var express = require('express'),
    http = require('http');
var app = express();
var cookie = require('cookie');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var redis = require('redis');
var client = redis.createClient();
var session = require('express-session');
var redisStore = require('connect-redis')(session);
io.set('transports', ['websocket']);

var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
const fs = require('fs');
require('./config/passport')(passport);


var sessionMiddleware = session({
    store:new redisStore({host:'localhost',port:6379,client:client}),
    secret:'secretTextchange',
    saveUninitialized:false,
    resave:false
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));

app.use(sessionMiddleware);
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

require('./routes/routes')(app,passport,client);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});
io.use(function(socket, next) {
    sessionMiddleware(socket.request, {}, next);
});
io.sockets.on('connection', function (socket) {
        console.log("verified");
        socket.on('message',function(msg){
            io.sockets.emit('rmessage', {
                name:socket.request.session.passport.user.name,
                avatarUrl:socket.request.session.passport.user.avatarUrl,
                message:msg
            });
        });

});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});
server.listen(3000);

module.exports = app;

passport.js

var OpenIDStrategy = require('passport-openid').Strategy;
var auth = require('./auth');
var steam = require('./steam');
var s = new steam({
    apiKey: auth.Steam.apiKey,
    format:'json'
})
module.exports = function(passport){

    passport.serializeUser(function(user, done) {

        done(null, user);
    });

    passport.deserializeUser(function(user, done) {


        done(null,user);
    });

    var SteamStrategy = new OpenIDStrategy({
            // OpenID provider configuration
            providerURL: auth.Steam.providerUrl,
            stateless: auth.Steam.stateless,
            // How the OpenID provider should return the client to us
            returnURL: auth.Steam.returnUrl,
            realm: auth.Steam.realm,
        },

        function(identifier, done) {

            process.nextTick(function () {
                console.log("passport-"+identifier);

                s.getPlayerSummaries({
                    steamids:identifier.match(/\d+$/)[0],
                    callback:function(err,data){
                        var user = {
                            steamid:identifier.match(/\d+$/)[0],
                            avatarUrl: data.response.players[0].avatar,
                            name:data.response.players[0].personaname
                        };
                        return done(null, user);
                    }
                });
                // In case of an error, we invoke done(err).
                // If we cannot find or don't like the login attempt, we invoke
                // done(null, false).
                // If everything went fine, we invoke done(null, user).
            });
        });

    passport.use(SteamStrategy);

}

routes.js

module.exports = function(app,passport,client){

    app.get('/', function (req,res) {
        res.render('index.ejs',{
                                user: req.user,
                               title:"yo"});
    });

    app.get('/auth',passport.authenticate('openid'));

    app.get('/auth/return',passport.authenticate('openid'),function(req,res){

        if (req.user) {
            res.redirect('/');
        } else {
            res.redirect('/');
        }
    });
}

1 个答案:

答案 0 :(得分:0)

你能用这个:https://www.npmjs.com/package/redis-sessions吗?

有一个名为soid的方法可以获取单个ID的所有会话。您可以在用户登录时查询用户的ID。然后从该ID获取所有会话。如果soid返回空,则可以安全地假设用户没有会话。如果它返回其中的内容,则用户有会话。

这是我现在最好的尝试。

祝你好运。