Authentication 如何使用护照后的承诺登录。通过社会服务验证。KeystoneJS+;护照

Authentication 如何使用护照后的承诺登录。通过社会服务验证。KeystoneJS+;护照,authentication,express,mongoose,keystonejs,passport.js,Authentication,Express,Mongoose,Keystonejs,Passport.js,除了我需要在这里发表,可能有人会帮助我,我会很感激的 我需要获得解锁应用程序中代码的帮助 我有两个服务,它们在得到回调后在会话中存储用户信息,并重定向到名为/auth/confirm/的页面 这是twitter auth的例子,对我来说非常适合 const keystone = require('keystone'); const passport = require('passport'); const passportTwitterStrategy = require('passport-t

除了我需要在这里发表,可能有人会帮助我,我会很感激的

我需要获得解锁应用程序中代码的帮助

我有两个服务,它们在得到回调后在会话中存储用户信息,并重定向到名为/auth/confirm/的页面

这是twitter auth的例子,对我来说非常适合

const keystone = require('keystone');
const passport = require('passport');
const passportTwitterStrategy = require('passport-twitter').Strategy;
const User = keystone.list('User');

const credentials = {
    consumerKey: process.env.TWITTER_CONSUMER_KEY,
    consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
    callbackURL: process.env.TWITTER_CALLBACK_URL,
    includeEmail: true
};

exports.authenticateUser = function(req, res, next) {

    const redirect = '/auth/confirm';

    const twitterStrategy = new passportTwitterStrategy(credentials, function(accessToken, refreshToken, profile, done) {
        done(null, {
            accessToken: accessToken,
            refreshToken: refreshToken,
            profile: profile
        });
    });

    // Pass through authentication to passport
    passport.use(twitterStrategy);

    // Save user data once returning from Twitter
    if (req.query.hasOwnProperty('cb')) {

        passport.authenticate('twitter', { session: false }, function(err, data, info) {

            if (err || !data) {
                return res.redirect('/signin');
            }

            const name = data.profile && data.profile.displayName ? data.profile.displayName.split(' ') : [];

            req.session.auth = {
                type: 'twitter',

                name: {
                    first: name.length ? name[0] : '',
                    last: name.length > 1 ? name[1] : ''
                },

                email: data.profile._json.email,

                profileId: data.profile.id,

                username: data.profile.username,

                avatar: data.profile._json.profile_image_url.replace('_normal', ''),

                accessToken: data.accessToken,
                refreshToken: data.refreshToken
            };

            return res.redirect(redirect);

        })(req, res, next);

        // Perform initial authentication request to Twitter
    } else {
        passport.authenticate('twitter')(req, res, next);
    }
};
现在,如果从用户处获得访问权限,我们将twitter用户存储在req.session.auth中。但是现在我有一个大问题。据我所知,Mongoose用户模型也是异步工作的,当我试图通过twitter profileID检查现有用户时,我无法得到正确的结果,因为它首先进入,然后回调,不等待检查结果。我不想让这个库成为异步库,但要避免异步库,因为对于一个特性来说,它太大了。我更喜欢使用新版本中的本机承诺。我不确定这一切,也不知道如何以最好的表现,非常期待有人会帮助我。无论如何-谢谢你的阅读

const keystone = require('keystone');
const User = keystone.list('User');

module.exports = (req, res, next) => {

    const locals = res.locals;

    locals.authUser = req.session.auth;

    // Set existing user if already logged in
    locals.existingUser = req.user || false;

    // Reject request if no auth data is stored in session
    if (!locals.authUser) {
        console.log('[auth.confirm] - No auth data detected, redirecting to signin.');
        console.log('------------------------------------------------------------');
        return res.redirect('/');
    }

    const authenticateUser = new Promise((resolve, reject) => {
        if (locals.existingUser) resolve(true);
        console.log('[auth.confirm] - Searching for existing users via [' + locals.authUser.type + '] profile id...');
        console.log('------------------------------------------------------------');
        User.model.findOne()
            .where('services.' + locals.authUser.type + '.profileId', locals.authUser.profileId)
            .exec((err, user) => {
                if (err) {
                    console.log('[auth.confirm] - Error finding existing user via profile id.', err);
                    console.log('------------------------------------------------------------');
                    reject(err);
                }
                if (user) {
                    console.log('[auth.confirm] - Found existing user via [' + locals.authUser.type + '] profile id...');
                    console.log('------------------------------------------------------------');
                    locals.existingUser = user;
                    resolve(true);
                }
                resolve(false);
            });
    });

    authenticateUser
        .then(result => {
            if (result) return result;
            User.model.findOne()
                .where('email', locals.authUser.email)
                .exec((err, user) => {
                    if (err) {
                        throw err;
                    }
                    if (user) {
                        locals.existingUser = user;
                    }
                    return false;
                });
        })
        .then(result => {
            if (result) return result;

            if (locals.existingUser) {
                const userData = {
                    email: locals.authUser.email,
                    services: locals.existingUser.services || {}
                };

                userData.services[locals.authUser.type] = {
                    isConfigured: true,
                    profileId: locals.authUser.profileId,
                    username: locals.authUser.username,
                    avatar: locals.authUser.avatar,
                    accessToken: locals.authUser.accessToken,
                    refreshToken: locals.authUser.refreshToken
                };

                locals.existingUser.set(userData);

                locals.existingUser.save(err => {
                    if (err) throw err;
                    return true;
                });

            } else {

                const userData = {
                    name: {
                        first: locals.authUser.name.first,
                        last: locals.authUser.name.last
                    },
                    email: locals.authUser.email,
                    password: Math.random().toString(36).slice(-8),
                    services: {}
                };

                userData.services[locals.authUser.type] = {
                    isConfigured: true,
                    profileId: locals.authUser.profileId,
                    username: locals.authUser.username,
                    avatar: locals.authUser.avatar,
                    accessToken: locals.authUser.accessToken,
                    refreshToken: locals.authUser.refreshToken
                };

                locals.existingUser = new User.model(userData);
                locals.existingUser.save(err => {
                    if (err) throw err;
                    return true;
                });
            }
        })
        .then(result => {
            console.log('[auth.confirm] - Signing in user...');
            console.log('------------------------------------------------------------');

            const onSuccess = user => {
                console.log('[auth.confirm] - Successfully signed in.');
                console.log('------------------------------------------------------------');
                return res.redirect(req.cookies.target || '/keystone');
            };

            const onFail = err => {
                console.log('[auth.confirm] - Failed signing in.', err);
                console.log('------------------------------------------------------------');
                if (err) throw err;
                return res.redirect('/');
            };

            keystone.session.signin(String(locals.existingUser._id), req, res, onSuccess, onFail);
        });

    return authenticateUser;
};

现在我的代码如下。它的工作和异步,但无论如何,我会很高兴得到别人的审查

const keystone = require('keystone');
const User = keystone.list('User');

module.exports = (req, res, next) => {

    const authUser = req.session.auth;

    // Reject request if no auth data is stored in session
    if (!authUser) {
        return res.redirect('/');
    }

    // Set existing user if already logged in
    if (req.user) return doSignIn(req.user);

    User.model.findOne()
        .where('services.' + authUser.type + '.profileId', authUser.profileId)
        .exec()
        .then(user => {
            if (user) return doSignIn(user);
            User.model.findOne()
                .where('email', authUser.email)
                .exec()
                .then(user => {
                    return createOrUpdateUser(user);
                }, err => {
                    if (err) {
                        throw err;
                    }
                });
        }, err => {
            throw err;
        });


    function doSignIn(user) {

        const onSuccess = user => {
            return res.redirect(req.cookies.target || '/keystone');
        };

        const onFail = err => {
            if (err) throw err;
            return res.redirect('/');
        };

        keystone.session.signin(String(user._id), req, res, onSuccess, onFail);
    }

    function createOrUpdateUser(user) {
        if (user) {

            const userData = {
                email: authUser.email,
                services: user.services || {}
            };

            userData.services[authUser.type] = {
                isConfigured: true,
                profileId: authUser.profileId,
                username: authUser.username,
                avatar: authUser.avatar,
                accessToken: authUser.accessToken,
                refreshToken: authUser.refreshToken
            };

            user.set(userData);

            user.save((err, user) => {
                if (err) throw err;
                return doSignIn(user);
            });

        } else {

            const userData = {
                name: {
                    first: authUser.name.first,
                    last: authUser.name.last
                },
                email: authUser.email,
                password: Math.random().toString(36).slice(-8),
                services: {}
            };

            userData.services[authUser.type] = {
                isConfigured: true,
                profileId: authUser.profileId,
                username: authUser.username,
                avatar: authUser.avatar,
                accessToken: authUser.accessToken,
                refreshToken: authUser.refreshToken
            };

            const newUser = new User.model(userData);

            newUser.save((err, user) => {
                if (err) throw err;
                return doSignIn(user);
            });
        }
    }
};