|
|
/* eslint no-unused-vars: ["error", { "args": "none" }] */
|
|
|
/**
|
|
|
* 登录
|
|
|
* @author: Bi Kai<kai.bi@yoho.cn>
|
|
|
* @date: 2016/05/09
|
|
|
*/
|
|
|
'use strict';
|
|
|
const _ = require('lodash');
|
|
|
const passport = require('passport');
|
|
|
|
|
|
// const md5 = require('yoho-md5');
|
|
|
const uuid = require('uuid');
|
|
|
const co = Promise.coroutine;
|
|
|
const cookie = global.yoho.cookie;
|
|
|
const helpers = global.yoho.helpers;
|
|
|
const log = global.yoho.logger;
|
|
|
const config = global.yoho.config;
|
|
|
const cache = global.yoho.cache;
|
|
|
const utils = require(global.utils);
|
|
|
const RegService = require('../models/reg-service');
|
|
|
const AuthHelper = require('../models/auth-helper');
|
|
|
|
|
|
const loginPage = `${config.siteUrl}/signin.html`;
|
|
|
|
|
|
function doPassportCallback(openId, nickname, sourceType, req, res) {
|
|
|
let shoppingKey = cookie.getShoppingKey(req);
|
|
|
let refer = req.cookies.refer;
|
|
|
|
|
|
if (refer) {
|
|
|
refer = decodeURI(req.cookies.refer);
|
|
|
} else {
|
|
|
refer = `${config.siteUrl}/home`;
|
|
|
}
|
|
|
|
|
|
if (/signin|login/.test(refer)) {
|
|
|
refer = `${config.siteUrl}/home`;
|
|
|
}
|
|
|
|
|
|
refer = utils.refererLimit(refer);
|
|
|
|
|
|
if (openId && nickname) {
|
|
|
return AuthHelper.signinByOpenID(nickname, openId, sourceType, shoppingKey).then((result) => {
|
|
|
if (result.code !== 200) {
|
|
|
return Promise.reject(result);
|
|
|
}
|
|
|
if (result.data['is_bind'] && result.data['is_bind'] === 'N') { //eslint-disable-line
|
|
|
return helpers.urlFormat('/passport/bind/index', {
|
|
|
openId: openId,
|
|
|
sourceType: sourceType,
|
|
|
refer: refer
|
|
|
});
|
|
|
} else if (result.code === 200 && result.data.uid) {
|
|
|
return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key).then(() => {
|
|
|
return refer;
|
|
|
});
|
|
|
}
|
|
|
}).then((redirectTo) => {
|
|
|
return res.redirect(redirectTo);
|
|
|
});
|
|
|
} 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.refererLimit(refer);
|
|
|
|
|
|
refer && !/signin|login|passport/.test(refer) && res.cookie('refer', encodeURI(refer), {
|
|
|
domain: 'yohobuy.com'
|
|
|
});
|
|
|
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.refererLimit(refer);
|
|
|
return res.redirect(refer);
|
|
|
}).catch(() => {
|
|
|
return next();
|
|
|
});
|
|
|
} else {
|
|
|
return next();
|
|
|
}
|
|
|
},
|
|
|
check: (req, res, next) => {
|
|
|
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 local = {
|
|
|
loginPage: (req, res) => {
|
|
|
// 是否关闭账号登录
|
|
|
let closePassword = _.get(req.app.locals.wap, 'close.passwordLogin', false);
|
|
|
|
|
|
if (closePassword) {
|
|
|
return res.redirect(`/signin.html?refer=${req.query.refer || ''}`);
|
|
|
}
|
|
|
if (req.session.captchaValidCount == null) { // eslint-disable-line
|
|
|
req.session.captchaValidCount = 5;
|
|
|
}
|
|
|
|
|
|
res.render('login', {
|
|
|
width750: true,
|
|
|
loginIndex: true, // 模板中使用JS的标识
|
|
|
captchaShow: req.yoho.captchaShow,
|
|
|
backUrl: 'javascript:history.go(-1)', // eslint-disable-line
|
|
|
showHeaderImg: true, // 控制显示头部图片
|
|
|
isPassportPage: true, // 模板中模块标识
|
|
|
smsLoginUrl: '/passport/sms_login',
|
|
|
registerUrl: '/passport/reg/index', // 注册的URL链接
|
|
|
aliLoginUrl: '/passport/login/alipay', // 支付宝快捷登录的URL链接
|
|
|
weiboLoginUrl: '/passport/login/sina', // 微博登录的URL链接
|
|
|
qqLoginUrl: '/passport/login/qq', // 腾讯QQ登录的URL链接
|
|
|
wechatLoginUrl: '/passport/login/wechat', // 微信登录的URL链接
|
|
|
internationalUrl: '/passport/international', // 国际号登录的URL链接
|
|
|
phoneRetriveUrl: '/passport/back/mobile', // 通过手机号找回密码的URL链接
|
|
|
emailRetriveUrl: '/passport/back/email', // 通过邮箱找回密码的URL链接
|
|
|
module: 'passport',
|
|
|
page: 'login',
|
|
|
title: '登录',
|
|
|
reg: true
|
|
|
});
|
|
|
},
|
|
|
international: (req, res) => {
|
|
|
// 是否关闭账号登录
|
|
|
let closePassword = _.get(req.app.locals.wap, 'close.passwordLogin', false);
|
|
|
|
|
|
if (closePassword) {
|
|
|
return res.redirect(`/signin.html?refer=${req.query.refer || ''}`);
|
|
|
}
|
|
|
if (req.session.captchaValidCount == null) { // eslint-disable-line
|
|
|
req.session.captchaValidCount = 5;
|
|
|
}
|
|
|
|
|
|
res.render('international', {
|
|
|
width750: true,
|
|
|
backUrl: 'javascript:history.go(-1)', // eslint-disable-line
|
|
|
loginInternational: true, // 模板中使用JS的标识
|
|
|
captchaShow: req.yoho.captchaShow,
|
|
|
isPassportPage: true, // 模板中模块标识
|
|
|
headerText: '登录',
|
|
|
areaCode: '+86', // 默认区号
|
|
|
countrys: RegService.getAreaData(), // 地区信息列表
|
|
|
module: 'passport',
|
|
|
page: 'international',
|
|
|
title: '国际账号登录'
|
|
|
});
|
|
|
},
|
|
|
login: (req, res, next) => {
|
|
|
// 是否关闭账号登录
|
|
|
let closePassword = _.get(req.app.locals.wap, 'close.passwordLogin', false);
|
|
|
|
|
|
if (closePassword) {
|
|
|
return res.json({
|
|
|
code: 403,
|
|
|
message: '请使用快速登录'
|
|
|
});
|
|
|
}
|
|
|
|
|
|
passport.authenticate('local', (err, user) => {
|
|
|
if (err || !user) {
|
|
|
if (err.code === 4189) {
|
|
|
let obj = {
|
|
|
code: 4189,
|
|
|
message: err || '登录出错请重试',
|
|
|
url: '//m.yohobuy.com/passport/sms_login'
|
|
|
};
|
|
|
|
|
|
return res.json(obj);
|
|
|
} else {
|
|
|
let obj = {
|
|
|
code: 400,
|
|
|
message: err || '登录出错请重试',
|
|
|
data: '',
|
|
|
captchaShow: true
|
|
|
};
|
|
|
|
|
|
cache.set(`loginErrorIp:${req.yoho.clientIp}`, true, 3600).catch(log.error);
|
|
|
return res.json(obj);
|
|
|
}
|
|
|
} else {
|
|
|
let refer = req.cookies.refer;
|
|
|
|
|
|
if (refer) {
|
|
|
refer = decodeURI(req.cookies.refer);
|
|
|
} else {
|
|
|
refer = `${config.siteUrl}/home`;
|
|
|
}
|
|
|
|
|
|
if (/sign|login/.test(refer)) {
|
|
|
refer = `${config.siteUrl}/home`;
|
|
|
}
|
|
|
|
|
|
refer = utils.refererLimit(refer);
|
|
|
|
|
|
user.session = refer;
|
|
|
user.href = refer;
|
|
|
res.cookie('_LOGIN_TYPE', 0, {
|
|
|
domain: 'm.yohobuy.com'
|
|
|
});
|
|
|
|
|
|
|
|
|
// 弱密码返回数据
|
|
|
let passwordWeakReturn;
|
|
|
|
|
|
if (user.weakPassword) {
|
|
|
req.session.passwordWeak = user;
|
|
|
passwordWeakReturn = {
|
|
|
code: 510,
|
|
|
url: '/passport/password/resetpage',
|
|
|
pwdTip: _.get(user, 'pwdTip', '密码应为6-20位字母、数字的组合'),
|
|
|
uid: _.get(user, 'uid', '')
|
|
|
};
|
|
|
}
|
|
|
|
|
|
// 不可以跳过,不登录用户
|
|
|
if (user.weakPassword && user.canSkip !== 'Y') {
|
|
|
return res.json(passwordWeakReturn);
|
|
|
}
|
|
|
|
|
|
AuthHelper.syncUserSession(user.uid, req, res, user.session_key).then(() => {
|
|
|
if (user.weakPassword) {
|
|
|
return res.json(passwordWeakReturn);
|
|
|
} else {
|
|
|
res.json({
|
|
|
code: 200,
|
|
|
data: user
|
|
|
});
|
|
|
}
|
|
|
}).catch(next);
|
|
|
}
|
|
|
})(req, res, next);
|
|
|
},
|
|
|
logout: (req, res) => {
|
|
|
res.clearCookie('_SPK');
|
|
|
res.cookie('_WX_PASS_LOGIN', true, {
|
|
|
domain: 'm.yohobuy.com'
|
|
|
});
|
|
|
let refer = req.get('Referer') || config.siteUrl;
|
|
|
|
|
|
refer = utils.refererLimit(refer);
|
|
|
res.redirect(refer);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const wechat = {
|
|
|
login: (req, res, next) => {
|
|
|
// 设置为原链接标识originalUrl
|
|
|
req.session.originalUrl = 'true';
|
|
|
req.session.authState = uuid.v4();
|
|
|
res.clearCookie('_WX_PASS_LOGIN', {
|
|
|
domain: 'm.yohobuy.com'
|
|
|
});
|
|
|
return passport.authenticate('weixin', {
|
|
|
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('weixin', (err, user) => {
|
|
|
if (err || !user) {
|
|
|
log.error(`wechat authenticate error : ${JSON.stringify(err)}`);
|
|
|
return res.redirect(loginPage);
|
|
|
}
|
|
|
let nickname = user._json.nickname || user.displayName;
|
|
|
let openId = user._json.unionid || user.id;
|
|
|
|
|
|
res.cookie('_WX_OPENID', _.get(user, '_json.openid'), {
|
|
|
domain: 'm.yohobuy.com'
|
|
|
});
|
|
|
res.cookie('_WX_UNIONID', _.get(user, '_json.unionid'), {
|
|
|
domain: 'm.yohobuy.com'
|
|
|
});
|
|
|
res.cookie('_LOGIN_TYPE', 4, {
|
|
|
domain: 'm.yohobuy.com'
|
|
|
});
|
|
|
doPassportCallback(openId, nickname, 'wechat', req, res).catch(next);
|
|
|
})(req, res, next);
|
|
|
} else {
|
|
|
log.error('Auth State Mismatch:' + req.originalUrl);
|
|
|
return res.redirect(loginPage);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const sina = {
|
|
|
login: (req, res, next) => {
|
|
|
// 设置为原链接标识originalUrl
|
|
|
req.session.originalUrl = 'true';
|
|
|
req.session.authState = uuid.v4();
|
|
|
return passport.authenticate('sina', {
|
|
|
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('sina', (err, user) => {
|
|
|
if (err || !user) {
|
|
|
log.error(`sina authenticate error : ${JSON.stringify(err)}`);
|
|
|
return res.redirect(loginPage);
|
|
|
}
|
|
|
let nickname = user.screen_name;
|
|
|
let openId = user.id;
|
|
|
|
|
|
res.cookie('_LOGIN_TYPE', 2, {
|
|
|
domain: 'm.yohobuy.com'
|
|
|
});
|
|
|
doPassportCallback(openId, nickname, 'sina', req, res).catch(next);
|
|
|
})(req, res, next);
|
|
|
} else {
|
|
|
log.error('Auth State Mismatch:' + req.originalUrl);
|
|
|
return res.redirect(loginPage);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const qq = {
|
|
|
login: (req, res, next) => {
|
|
|
// 设置为原链接标识originalUrl
|
|
|
req.session.originalUrl = 'true';
|
|
|
req.session.authState = uuid.v4();
|
|
|
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.redirect(loginPage);
|
|
|
}
|
|
|
|
|
|
let nickname = user.nickname;
|
|
|
let openId = user.id;
|
|
|
|
|
|
res.cookie('_LOGIN_TYPE', 1, {
|
|
|
domain: 'm.yohobuy.com'
|
|
|
});
|
|
|
doPassportCallback(openId, nickname, 'qq', req, res).catch(next);
|
|
|
})(req, res, next);
|
|
|
} else {
|
|
|
log.error('Auth State Mismatch:' + req.originalUrl);
|
|
|
return res.redirect(loginPage);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const alipay = {
|
|
|
login: (req, res, next) => {
|
|
|
// 设置为原链接标识originalUrl
|
|
|
req.session.originalUrl = 'true';
|
|
|
return passport.authenticate('alipay')(req, res, next);
|
|
|
},
|
|
|
callback: (req, res, next) => {
|
|
|
passport.authenticate('alipay', (err, user) => {
|
|
|
if (err || !user) {
|
|
|
log.error(`alipay authenticate error : ${JSON.stringify(err)}`);
|
|
|
return res.redirect(loginPage);
|
|
|
}
|
|
|
let nickname = user.realName;
|
|
|
let openId = user.userId;
|
|
|
|
|
|
res.cookie('_LOGIN_TYPE', 3, {
|
|
|
domain: 'm.yohobuy.com'
|
|
|
});
|
|
|
doPassportCallback(openId, nickname, 'alipay', req, res).catch(next);
|
|
|
})(req, res, next);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
exports.user = function(req, res, next) {
|
|
|
let result = {
|
|
|
code: 403,
|
|
|
message: '未登录',
|
|
|
data: ''
|
|
|
};
|
|
|
|
|
|
if (req.user.uid) {
|
|
|
result.code = 200;
|
|
|
result.message = '已登录';
|
|
|
result.data = req.user.uid.toString();
|
|
|
}
|
|
|
res.jsonp(result);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 中间件
|
|
|
* 根据用户登录是否成功决定是否展示验证码
|
|
|
*/
|
|
|
exports.loginShowCaptchaByIp = function(req, res, next) {
|
|
|
// 总开关状态
|
|
|
req.yoho.captchaShow = !_.get(req.app.locals.wap, 'close.loginValidation', false);
|
|
|
|
|
|
// 开关打开,不走任何验证逻辑
|
|
|
if (!req.yoho.captchaShow) {
|
|
|
return next();
|
|
|
} else {
|
|
|
req.yoho.captchaShow = false;
|
|
|
}
|
|
|
|
|
|
co(function*() {
|
|
|
let hasErrorLog = yield cache.get(`loginErrorIp:${req.yoho.clientIp}`);
|
|
|
|
|
|
log.info(`Pagerender clientip ${req.yoho.clientIp} status is ` + hasErrorLog);
|
|
|
|
|
|
if (hasErrorLog) {
|
|
|
req.yoho.captchaShow = true;
|
|
|
}
|
|
|
next();
|
|
|
})().catch(function(e) {
|
|
|
req.yoho.captchaShow = true;
|
|
|
next();
|
|
|
});
|
|
|
};
|
|
|
|
|
|
exports.common = common;
|
|
|
exports.local = local;
|
|
|
exports.wechat = wechat;
|
|
|
exports.sina = sina;
|
|
|
exports.qq = qq;
|
|
|
exports.alipay = alipay; |