修改req.user还是使用req.account?

Modify req.user or use req.account?

我正在开发一个带有护照的普通应用程序,我 运行 解决了这个问题:

我有一个LocalStrategy来根据应用程序数据库登录用户。但是,我需要使用可能的多个帐户同时在另一项服务上登录用户。问题是,一旦我路由授权这些登录,并将变量设置为 req.account,我就无法在其他路由中访问它们。请注意,我可以获得我想要的数据,我只是想从这条路线以外的其他地方访问它,比如 req.user。我将 post 我的一些代码来澄清情况。

本地登录路由

app.post('/login', function (req, res, next) {
    passport.authenticate('local-login', function (err, user) {
        if (err)
            return next(err);
        if (!user)
            return res.status(400).json({status: 'Invalid Username'});
        req.login(user, function (err) {
            if (err)
                return next(err);
            res.status(200).json({status: 'User successfully authenticated'});
        });
    })(req, res, next);
});

本地登录密码配置

passport.use('local-login', new LocalStrategy(function (user, pswd, done) {
    User.findOne({'username': user}, function (err, user) {
        if (err)
            return done(err);
        if (!user || !user.validPassword(pswd))
            return done(null, false);
        return done(null, user);
    });
}));

其他服务通行证配置

passport.use('other-login', new OtherStrategy(function (docs, done) {
    if (docs.length === 0)
        return done(null, false);

    var accounts = [];
    var user, pswd, data;
    var counter = docs.length;
    for (var i = 0; i < docs.length; i++) {
        user = docs[i]._id;
        pswd = docs[i].password;
        request.post(<serviceurl>, {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: qs.stringify({
                grant_type: 'password',
                username: user,
                password: pswd,
                client_id: process.env.API_KEY
            })
        }, function (err, res, body) {
            if (err)
                return done(err);
            data = JSON.parse(body);
            data.username = docs[docs.length - counter]._id;
            accounts.push(data);
            counter--;
            if (counter === 0)
                return done(null, accounts);
        });
    }
}));

其他服务路线

router.get('/otherservice', passport.authorize('other-login', {}) , function (req, res) {
    console.log(req.account);
    res.sendStatus(200);
});

其他服务认证(来自自定义策略)

ServiceStrategy.prototype.authenticate = function (req) {
var self = this;

var id = req.user.master_id || req.user.id;
Service.find({master_id: id}, function (err, docs){
    if (err)
        return self.error(err);

    function verified(err, data, info) {
        if (err) { return self.error(err); }
        if (!data) { return self.fail(info); }
        self.success(data, info);
    }

    try {
        if (self._passReqToCallback) {
            self._verify(req, docs, verified);
        } else {
            self._verify(docs, verified);
        }
    } catch (ex) {
        return self.error(ex);
    }
});};

我找到了解决办法!在用户模型上,我添加了一个 accounts 属性 来存储授权返回的数据。然后,在授权路线上,我用这个信息更新了用户,并保存了。一点也不难。

app.post('/api/login', function (req, res, next) {
    passport.authenticate('local-login', function (err, user) {
        if (err)
            return next(err);
        if (!user)
            return res.status(400).json({status: 'Invalid Username'});
        req.login(user, function (err) {
            if (err)
                return next(err);
            var id = req.user.master_id || req.user.id;
            Service.findOne({master_id: id}, function (err, doc) {
                if (doc == null)
                    res.status(200).json({
                        status: 'User successfully authenticated',
                        accounts: false
                    });
                else
                    return next();
            });
        });
    })(req, res, next);
}, passport.authorize('other-login', {}), function (req, res) {
    var accounts = req.account;
    var user = req.user;
    user.accounts = accounts;
    user.save(function (err, newUser) {
        if (err)
            throw err;
        res.status(200).json({
            status: 'User sucessfully authenticated',
            accounts: true
        });
    })
});