【问题标题】:How to clear cookies when error deserialize a user using passport.js?使用passport.js反序列化用户出错时如何清除cookie?
【发布时间】:2020-06-01 05:18:33
【问题描述】:

当我使用passport.deserializeUser处理程序时:

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

如果使用err 调用done,我是否有机会清除cookie 并将用户重定向到/login 页面?该功能是否取决于我使用的策略?例如。使用本地策略的failureRedirect 选项?

【问题讨论】:

    标签: javascript node.js passport.js


    【解决方案1】:

    我用过continuation local storage,并在护照前注册。

    var createNamespace = require('continuation-local-storage').createNamespace;
    var writer = createNamespace('express');
    
    app.use((req,res,next) => {
        namespace.bindEmitter(req);
        namespace.bindEmitter(res);
        namespace.run(() => {
            writer.set('req', req)
            writer.set('res', res);
            next()
        });
    });
    
    app.use(passport.initialize(), passport.session());
    

    然后在您的反序列化中,您可以访问相同的命名空间并将值提取出来:

    var getNamespace = require('continuation-local-storage').getNamespace;
    var reader = getNamespace('express');
    
    function deserialize(key, done) {
       try {
          ...
       } catch(e) {
          reader.get("req").logout()
       }
    }
    

    【讨论】:

    • 模块本身看起来完全是 hack!但这看起来真的很好!
    • 这有点像 hack,尤其是考虑到 Node 如何处理不同位置的 I/O(事件与回调等)。 Angular2 实际上是建立在称为zone.js 的类似技术之上的。它旨在成为一个猴子补丁,以最大限度地减少普通开发人员必须调用的自定义代码量。
    【解决方案2】:

    您可以做的是使用req.session.destroy 方法....所以在您的情况下:

    passport.deserializeUser(function(id, done) {
      User.findById(id, function(err, user) {
        done(err, user);
        req.session.destroy();
      });
    });
    

    而且技术上可能不会“完全”注销您应用中的人,因此如果您想要替代方法,可以使用提供的 clearCookie 方法:

    passport.deserializeUser(function(id, done) {
      User.findById(id, function(err, user) {
        done(err, user);
          req.session.destroy(function() {
          res.clearCookie('connect.sid');
          res.redirect('/');
        });
      });
    });
    

    【讨论】:

    • 谢谢,但我在哪里可以获得 req 变量?
    • 是的,我正在使用快递。但是这个 deserializeUser 回调没有在快速路由处理程序中定义。
    • 谢谢。我不是在尝试用户发起的注销。我正在尝试通过清除 cookie 来处理错误,以便用户重新登录。
    • 对不起,这不是正确的答案。至少在编辑之前不会。 req 对象在这里不可用,因为 passport.js 的 api 没有提供它。这不会发生在快速路由处理程序中。
    • 这是注销按钮@Daiwei 吗?
    【解决方案3】:

    就像@amanuel2 指出的那样,您可以使用 req 来销毁会话。如果您要求,护照将通过reqdeserializeUser

    passport.deserializeUser(function(req, id, done) {
        User.findById(id, function(err, user) {
            if (err) {
                req.session.destroy(function() {
                   return done(err)
                }
            }
            done(null, user);
        });
    });
    

    因此,如果反序列化会话出现问题,您可以销毁会话、重定向等。

    【讨论】:

      猜你喜欢
      • 2018-10-22
      • 1970-01-01
      • 2013-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多