login.js 6.25 KB
'use strict';
const _ = require('lodash');
const passport = require('passport');
const uuid = require('uuid');
const helpers = global.yoho.helpers;
const log = global.yoho.logger;
const config = global.yoho.config;
const utils = global.yoho.utils;
const AuthHelper = require('../models/auth-helper');
const loginPage = `${config.siteUrl}/signin.html`;

function doPassportCallback(openId, nickname, source, req, res) { // eslint-disable-line
    if (openId && nickname && source) {
        req.session._THIRD_LOGIN_INFO = {
            openId,
            nickname,
            source
        };

        // 第三方登录
        req.session._THIRD_LOGIN = true;
        req.session._THIRD_LOGIN_SOURCE = source;

        res.status(301).redirect(`${req.session.cbUrl}`);
    } else {
        return Promise.reject('missing third party login openId or nickname');
    }
}

const common = {
    beforeLogin: (req, res, next) => {
        if (req.session.passwordWeak) {
            return res.redirect('/passport/password/resetpage');
        }

        let refer = req.query.refer;

        if (!refer) {
            refer = req.get('Referer') || req.cookies.refer;
        }

        refer = utils.yoho.refererLimit(refer);

        refer && !/signin|login|passport/.test(refer) && res.cookie('refer', encodeURI(refer), {
            domain: 'yohobuy.com'
        });

        let from = req.query.from;

        if (from) {
            res.cookie('from', from, {
                domain: 'yohobuy.com',
                expires: new Date(Date.now() + 10 * 60 * 1000)
            });
        }

        if (req.yoho.isApp) {
            return next({
                code: 401,
                message: 'weblogin',
                refer
            });
        }
        next();
    },
    weixinCheck: (req, res, next) => {
        let passLogin = _.get(req, 'cookies._WX_PASS_LOGIN', false);

        if (req.yoho.isWechat && !passLogin) {
            return res.redirect(helpers.urlFormat('/passport/login/wechat', {
                refer: req.query.refer || req.get('Referer') || '/'
            }));
        }
        next();
    },
    clearCookie: (req, res, next) => {
        res.clearCookie('_SESSION_KEY', {
            domain: 'yohobuy.com'
        });
        res.clearCookie('_UID', {
            domain: 'yohobuy.com'
        });
        res.clearCookie('_TOKEN', {
            domain: 'yohobuy.com'
        });
        if (req.session2 && req.session2.reset) {
            req.session2.reset();
        }
        if (req.session && req.session.regenerate) {
            return req.session.regenerate(() => {
                return next();
            });
        }
    },
    isLoginUser: (req, res, next) => {
        // 微信里边已经登录的时候,不再跳转登录
        if (req.user.uid) {
            AuthHelper.profile(req.user.uid).then(function(result) {
                if (result.code !== 200) {
                    return next();
                }
                let refer = req.query.refer || decodeURI(req.cookies.refer) || config.siteUrl;

                if (/sign|login/.test(refer)) {
                    refer = `${config.siteUrl}/home`;
                }

                refer = utils.yoho.refererLimit(refer);
                return res.redirect(refer);
            }).catch(() => {
                return next();
            });
        } else {
            return next();
        }
    },
    check: (req, res) => {
        let refer = req.query.refer;

        // 短信推广的链接强制检查登录
        if (req.user.uid) {
            AuthHelper.profile(req.user.uid).then(function(result) {
                if (result && result.code === 200) {
                    return res.redirect(refer);
                }

                return res.redirect(helpers.urlFormat('/signin.html', {
                    refer: refer
                }));
            }).catch(() => {
                return res.redirect(helpers.urlFormat('/signin.html', {
                    refer: refer
                }));
            });
        } else {
            return res.redirect(helpers.urlFormat('/signin.html', {
                refer: refer
            }));
        }
    }
};


const wechat = {
    login: (req, res, next) => {
        req.session.originalUrl = 'true';
        req.session.authState = uuid.v4();
        req.session.cbUrl = req.query.cbUrl;

        return passport.authenticate('weixin', {
            state: req.session.authState
        })(req, res, next);
    },
    callback: (req, res) => {
        const openId = req.query.openId;
        const nickname = req.query.nickname;

        doPassportCallback(openId, nickname, 'qq', req, res);
    }
};

const sina = {
    login: (req, res, next) => {
        req.session.originalUrl = 'true';
        req.session.authState = uuid.v4();
        req.session.cbUrl = req.query.cbUrl;

        return passport.authenticate('sina', {
            state: req.session.authState
        })(req, res, next);
    },
    callback: (req, res) => {
        const openId = req.query.openId;
        const nickname = req.query.nickname;

        doPassportCallback(openId, nickname, 'sina', req, res);
    }
};

const qq = {
    login: (req, res, next) => {
        req.session.originalUrl = 'true';
        req.session.authState = uuid.v4();
        req.session.cbUrl = req.query.cbUrl;

        return passport.authenticate('qq', {
            state: req.session.authState
        })(req, res, next);
    },
    callback: (req, res, next) => {
        if (req.session && req.session.authState && req.session.authState === req.query.state) {
            passport.authenticate('qq', (err, user) => {
                if (err) {
                    log.error(`qq authenticate error : ${JSON.stringify(err)}`);

                    return res.json({
                        code: 500,
                        message: 'authenticate error'
                    });
                }

                let nickname = user.nickname;
                let openId = user.id;

                doPassportCallback(openId, nickname, 'qq', req, res);
            })(req, res, next);
        } else {
            log.error('Auth State Mismatch:' + req.originalUrl);
            return res.redirect(loginPage);
        }
    }
};

exports.common = common;
exports.wechat = wechat;
exports.sina = sina;
exports.qq = qq;