草庐IT

javascript - Session Node.js + Passport.js + Redis,通过user.id存储 session

coder 2023-07-18 原文

当用户登录时,会为他创建一个 session ,但如果他转到另一台计算机并登录,则会为他的帐户创建第二个 session 。我想做到这一点,以便用户不能超过一个有效 session 。有没有办法通过user.steamId把session存在redis中,这样他的第一个session就失效了?

任何帮助都将非常感谢!

应用程序.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);

}

路由.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('/');
        }
    });
}

最佳答案

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

有一个名为 soid 的方法,它可以获取单个 ID 的所有 session 。您可以在用户登录时查询他们的 ID。然后从该 ID 获取所有 session 。如果 soid 返回空,您可以安全地假设用户没有 session 。如果它返回时里面有东西,那么用户就有了 session 。

这是我目前最好的尝试。

祝你好运。

关于javascript - Session Node.js + Passport.js + Redis,通过user.id存储 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35076481/

有关javascript - Session Node.js + Passport.js + Redis,通过user.id存储 session的更多相关文章

  1. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  4. ruby-on-rails - Rails 优雅地处理超时 session ? - 2

    使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p

  5. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  6. ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序 - 2

    我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于

  7. ruby - Rails -- :id attribute? 所需的数据库索引 - 2

    因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration

  8. ruby-on-rails - 禁用设备的 :confirmable on-the-fly to batch-generate users - 2

    Devise是一个Ruby库,它为我提供了这个User类:classUser当写入:confirmable时,注册时会发送一封确认邮件。上周我不得不批量创建300个用户,所以我在恢复之前注释掉了:confirmable几分钟。现在我正在为用户批量创建创建一个UI,因此我需要即时添加/删除:confirmable。(我也可以直接修改Devise的源码,但我宁愿不去调和它)问题:如何即时添加/删除:confirmable? 最佳答案 WayneConrad的解决方案:user=User.newuser.skip_confirmation

  9. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  10. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

随机推荐