修改req.user或使用req.account?

时间:2016-05-11 15:02:43

标签: node.js express mean passport.js

我正在开发一个带护照的平均应用程序,我正在解决这个问题:

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

本地登录路线

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);
    }
});};

1 个答案:

答案 0 :(得分:1)

我找到了解决方案!在用户模型上,我添加了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
        });
    })
});