为什么在节点PassportJS不注销删除会议(Why is PassportJS in Node

2019-06-21 17:25发布

我无法让我的系统PassportJS注销。 看来注销路线被调用,但它不删除会话。 我想它返回401,如果在特定航线的用户没有登录。 我打电话的authenticateUser检查,如果用户登录。

非常感谢!

/******* This in index.js *********/
// setup passport for username & passport authentication
adminToolsSetup.setup(passport);

// admin tool login/logout logic
app.post("/adminTool/login",
    passport.authenticate('local', {
        successRedirect: '/adminTool/index.html',
        failureRedirect: '/',
        failureFlash: false })
);
app.get('/adminTool/logout', adminToolsSetup.authenticateUser, function(req, res){
    console.log("logging out");
    console.log(res.user);
    req.logout();
    res.redirect('/');
});


// ******* This is in adminToolSetup ********
// Setting up user authentication to be using user name and passport as authentication method,
// this function will fetch the user information from the user name, and compare the password     for authentication
exports.setup = function(passport) {
    setupLocalStrategy(passport);
    setupSerialization(passport);
}

function setupLocalStrategy(passport) {
    passport.use(new LocalStrategy(
        function(username, password, done) {
            console.log('validating user login');
            dao.retrieveAdminbyName(username, function(err, user) {
                if (err) { return done(err); }
                if (!user) {
                    return done(null, false, { message: 'Incorrect username.' });
                }
                // has password then compare password
                var hashedPassword = crypto.createHash('md5').update(password).digest("hex");
                if (user.adminPassword != hashedPassword) {
                    console.log('incorrect password');
                    return done(null, false, { message: 'Incorrect password.' });
                }
                console.log('user validated');
                return done(null, user);
            });
        }
    ));
}

function setupSerialization(passport) {
    // serialization
    passport.serializeUser(function(user, done) {
        console.log("serialize user");
        done(null, user.adminId);
    });

    // de-serialization
    passport.deserializeUser(function(id, done) {
        dao.retrieveUserById(id, function(err, user) {
            console.log("de-serialize user");
            done(err, user);
        });
    });
}

// authenticating the user as needed
exports.authenticateUser = function(req, res, next) {
    console.log(req.user);
    if (!req.user) {
        return res.send("401 unauthorized", 401);
    }
    next();
}

Answer 1:

布莱斯的答案是伟大的 ,但我还是注意到一个重要的区别,使; 护照引导建议使用.logout()也别名为.logOut()作为这样的:

app.get('/logout', function(req, res){
  req.logout();
  res.redirect('/'); //Can fire before session is destroyed?
});

但正如上面提到的,这是不可靠的。 我发现它的表现实现布莱斯的建议,这样当预期:

app.get('/logout', function (req, res){
  req.session.destroy(function (err) {
    res.redirect('/'); //Inside a callback… bulletproof!
  });
});

希望这可以帮助!



Answer 2:

遇到同样的问题。 使用req.session.destroy(); 代替req.logout(); 的作品,但我不知道这是不是最好的做法。



Answer 3:

session.destroy可能不足,以确保用户完全注销你要清楚会话cookie为好。

这里的问题是,如果您的应用程序也被用来作为一个单一的网页应用程序的API(不推荐,但很常见的),那么可以有一些要求(一个或多个)快递是注销之前启动和退出结束后进行处理。 如果是这样的话,那么它已被删除后,该更长的运行要求将在Redis的恢复会话。 而且,由于浏览器仍具有相同的cookie,你打开,你会成功登录页面的下一次。

req.session.destroy(function() {
    res.clearCookie('connect.sid');
    res.redirect('/');
});

那是什么也许发生的事情,否则:

  1. REQ 1(任何请求)被接收
  2. 从Redis的内存所需物品1个载荷会议
  3. 接收的注销REQ
  4. 注销REQ负荷会议
  5. 注销REQ破坏会议
  6. 注销REQ发送重定向到浏览器(Cookie未移除)
  7. 所需物品1完成处理
  8. 所需物品1从内存到Redis的保存会话
  9. 用户打开页面,而不登录对话框,因为无论是饼干和会话到位

理想情况下,你需要使用的API调用,并在只加载页面的Web应用程序只使用会话令牌身份验证,但即使你的web应用程序只用于获得API令牌这场比赛的条件仍然是可能的。



Answer 4:

我也有同样的问题,它在所有被证明无法与护照功能的问题,而是在路上,我打电话给我/logout路线。 我用取来调用路线:

(坏)

fetch('/auth/logout')
  .then([other stuff]);

事实证明这样做不会对会话持续不发送cookie,我猜res.logout()被应用到不同的会话? 无论如何,执行以下步骤修复它的权利了起来:

(好)

fetch('/auth/logout', { credentials: 'same-origin' })
  .then([other stuff]);


Answer 5:

我也有同样的问题,大写的O固定它;

app.get('/logout', function (req, res){
  req.logOut()  // <-- not req.logout();
  res.redirect('/')
});

编辑:这不再是一个问题。



Answer 6:

最近我有同样的问题,没有答案的固定问题对我来说。 可能是错误的,但它似乎有一个竞争条件做。

更改会议细节,下面的选项似乎已经解决了这个问题对我来说。 我测试了它的10倍左右,现在,一切似乎正常工作。

app.use(session({
    secret: 'secret',
    saveUninitialized: false,
    resave: false
}));

基本上我只是改变saveUninitializedresavetruefalse 。 这似乎已经解决了这一问题。

仅供参考我使用的标准req.logout(); 方法在我退出路径。 我不使用会话销毁像其他人提到。

app.get('/logout', function(req, res) {
    req.logout();
    res.redirect('/');
});


Answer 7:

我用两个req.logout()req.session.destroy()和正常工作。

server.get('/logout', (req, res) => {
  req.logout();
  req.session.destroy();
  res.redirect('/');
});

刚才说了,我使用的Redis作为会话存储。



Answer 8:

自行销毁会话看起来怪怪的。 我面临着有一个配置这个问题:

"express": "^4.12.3",
"passport": "^0.2.1",
"passport-local": "^1.0.0",

我应该说,此配置运作良好 。 我的问题的原因是在定制sessionStore ,我这里定义:

app.use(expressSession({
    ...
    store: dbSessionStore,
    ...
}));

为了确保您的问题在这里也只是发表评论商店线和无会话持续存在的运行。 如果它的工作,你应该深入到您的自定义会话存储。 在我的情况下set方法的定义是错误的。 当您使用req.logout()会话存储destroy() ,因为我以为以前的方法不被调用。 相反,调用set与更新后的会话方法。

祝你好运,我希望这回答会帮助你。



Answer 9:

我得到的,有时是因为你没有设置正确的护照不工作的经历。 例如,我做vhost ,但主要的应用程序我安装的护照这样是不对的。

app.js(为什么错了?请查看下面blockqoute)

require('./modules/middleware.bodyparser')(app);
require('./modules/middleware.passport')(app);
require('./modules/middleware.session')(app);
require('./modules/app.config.default.js')(app, express);

// default router across domain
app.use('/login', require('./controllers/loginController'));
app.get('/logout', function (req, res) {
    req.logout();
    res.redirect('/');
});

// vhost setup
app.use(vhost('sub1.somehost.dev', require('./app.host.sub1.js')));
app.use(vhost('somehost.dev', require('./app.host.main.js')));

实际上,它必须不能够登录,但我能做到这一点,因为我继续做多的错误。 通过把其他国家的护照设置在这里,所以会议的形式app.js可供app.host.sub1.js

app.host.sub1.js

// default app configuration
require('./modules/middleware.passport')(app);
require('./modules/app.config.default.js')(app, express);

所以,当我想退出......这不是工作,因为app.js是做错事的开始初始化passport.jsexpress-session.js ,这是不对的!。

然而,这个代码可以解决反正问题为他人提及。

app.js

app.get('/logout', function (req, res) {
    req.logout();
    req.session.destroy(function (err) {
        if (err) {
            return next(err);
        }

        // destroy session data
        req.session = null;

        // redirect to homepage
        res.redirect('/');
    });
});

但在我的情况下,正确的方法是...交换passport.js之前明确,session.js

文件还提到

请注意,启用会话支持完全是可选的,但建议对大多数应用。 如果启用,一定要使用passport.session()之前express.session(),以确保登录会话以正确的顺序恢复。

因此,解决了我的情况下,通过注销的问题..

app.js

require('./modules/middleware.bodyparser')(app);
require('./modules/middleware.session')(app);
require('./modules/middleware.passport')(app);
require('./modules/app.config.default.js')(app, express);


// default router across domain
app.use('/login', require('./controllers/loginController'));
app.get('/logout', function (req, res) {
    req.logout();
    res.redirect('/');
});

app.host.sub1.js

// default app configuration
require('./modules/app.config.default.js')(app, express);

现在req.logout(); 是现在的工作。



Answer 10:

答案都不为我工作,所以我会分享我的

app.use(session({
    secret: 'some_secret',
    resave: false,
    saveUninitialized: false,
   cookie: {maxAge: 1000} // this is the key
}))

router.get('/logout', (req, res, next) => {
    req.logOut()
    req.redirect('/')
})


Answer 11:

我也有同样的问题。 原来,我的护照的版本是不是快4.0兼容。 只需要安装一个旧版本。

    npm install --save express@3.0.0


Answer 12:

这为我工作:

app.get('/user', restrictRoute, function (req, res) {
  res.header('Cache-Control', 'no-cache, private, no-store, must-revalidate,
              max-stale=0, post-check=0, pre-check=0');
});

它确保您的页面将不会存储在缓存中



Answer 13:

我有一个程序员,这表明除去REQ的用户工作:

app.get('/logout', function (req, res){
  req.session.destroy(function (err) {
    req.user = null;
    res.redirect('/'); //Inside a callback… bulletproof!
  });
});

原因:我们需要从REQ删除(passportjs也这样做,但异步方式),因为注销后不使用的用户数据,即使这样会节省内存,也可能是passportjs发现用户数据,并可以创建新的会话和重定向(但不尚未发生)通过的途径,这是我们的责任,去除不相关的事情。 PassportJS登录后分配到的数据和req.user也去掉,如果我们使用req.logout(),但它可能无法正常工作的一些倍异步的NodeJS在本质



Answer 14:

我有护照0.3.2所面临的类似问题。

当我使用自定义回调的护照登录立即登记,并在问题依然存在。

这个问题是通过升级到0.4.0护照和增加线路解决

app.get('/logout', function(req, res) {
    req.logOut();
    res.redirect('/');
});


Answer 15:

显然,有这种问题的多种可能的原因。 在我的情况下,问题是声明的顺序不对,即注销终点护照初始化之前宣布。 正确的顺序是:

app.use(passport.initialize());
app.use(passport.session());


app.get('/logout', function(req, res) {
  req.logout();
  res.redirect('/');
});


Answer 16:

由于您使用Passport身份验证它使用它通过自己的会话connect.sid的cookie这个简单的处理退出是让护照处理会话的方式。

app.get('/logout', function(req, res){
  if (req.isAuthenticated()) {
    req.logOut()
    return res.redirect('/') // Handle valid logout
  }

  return res.status(401) // Handle unauthenticated response
})


Answer 17:

这里所有的例子做req.session.destroy后重定向。 但是一定要明白,Express将立即创建一个新的会话要重定向到该页面。 在与邮差组合,我发现了奇怪的行为,这样做注销后,护照,登录正确的给出了护照成功,但用户ID不能存储到会话文件中的作用。 其原因是,邮差需要更新该组所有请求的cookie中,这需要一段时间。 另外在销毁回调重定向没有帮助。

我不这样做的重定向,但却只是返回JSON消息解决它。



Answer 18:

您shoulde是使用req.logout()摧毁在浏览器会话。

app.get('/logout', function(req, res) {
    req.logout();
    res.redirect('/'); // whatever the route to your default page is
});


Answer 19:

我不知道如何,但ng-href="/signout"解决我的问题。 以前我用的服务,注销,而是我直接使用它。



Answer 20:

在我的情况下,使用一个回调传递给req.session.destroy只帮助了一些时间,我不得不求助于这个技巧:

req.session.destroy();
setTimeout(function() {
    res.redirect "/";
}, 2000);

我不知道为什么,就是这样,我已经能够去工作,唯一的解决办法,但遗憾的是@ JulianLloyd的回答并没有为我工作始终。

它可能是与我生活的登录页使用SSL(我一直无法重现的临时网站或我的本地主机的问题)的事实。 有可能是别的东西在我的应用程序也正在进行; 我使用的是德比护照模块,因为我的应用程序是使用德比框架,所以它难以分离的问题。

这显然是一个时间的问题,因为我第一次尝试为100毫秒,这是不够的超时。

不幸的是我还没有找到一个更好的解决方案。



文章来源: Why is PassportJS in Node not removing session on logout