Authored by 郭成尧

merge-master

@@ -148,17 +148,6 @@ app.use((req, res, next) => { @@ -148,17 +148,6 @@ app.use((req, res, next) => {
148 req.yoho = {}; // req和res绑定yoho对象,用于传递全局数据, 如req.yoho.channel等 148 req.yoho = {}; // req和res绑定yoho对象,用于传递全局数据, 如req.yoho.channel等
149 req.app.locals.wap = app.locals.wap; // zookeper对象赋值 149 req.app.locals.wap = app.locals.wap; // zookeper对象赋值
150 150
151 - // 临时增加错误日志记录  
152 - let sendJson = res.json;  
153 -  
154 - res.json = function(...args) {  
155 - try {  
156 - sendJson(...args);  
157 - } catch (e) {  
158 - logger.error(`res.json error data: ${JSON.stringify(args)}`);  
159 - }  
160 - };  
161 -  
162 next(); 151 next();
163 }); 152 });
164 153
@@ -241,7 +241,7 @@ const getPriceGiftList = (promotionIds, promotionType) => { @@ -241,7 +241,7 @@ const getPriceGiftList = (promotionIds, promotionType) => {
241 method: 'app.Shopping.queryPromotionGifts', 241 method: 'app.Shopping.queryPromotionGifts',
242 promotion_ids: promotionIds 242 promotion_ids: promotionIds
243 }).then((data) => { 243 }).then((data) => {
244 - return data.code === 200 ? cartProcess.procPriceGiftData(data.data, promotionType) : void 0; 244 + return data.code === 200 ? cartProcess.procPriceGiftData(data.data, promotionType) : {};
245 }); 245 });
246 }; 246 };
247 247
@@ -201,7 +201,7 @@ const packageData = (id, isApp, isWeixin, channel, isShare) => { @@ -201,7 +201,7 @@ const packageData = (id, isApp, isWeixin, channel, isShare) => {
201 201
202 return Promise.all(promises).then(datas => { 202 return Promise.all(promises).then(datas => {
203 203
204 - let getArticleContent = {}; 204 + let getArticleContent = [];
205 205
206 if (datas) { 206 if (datas) {
207 if (datas[1]) { 207 if (datas[1]) {
@@ -10,10 +10,12 @@ const passport = require('passport'); @@ -10,10 +10,12 @@ const passport = require('passport');
10 10
11 // const md5 = require('yoho-md5'); 11 // const md5 = require('yoho-md5');
12 const uuid = require('uuid'); 12 const uuid = require('uuid');
  13 +const co = Promise.coroutine;
13 const cookie = global.yoho.cookie; 14 const cookie = global.yoho.cookie;
14 const helpers = global.yoho.helpers; 15 const helpers = global.yoho.helpers;
15 const log = global.yoho.logger; 16 const log = global.yoho.logger;
16 const config = global.yoho.config; 17 const config = global.yoho.config;
  18 +const cache = global.yoho.cache;
17 const utils = require(global.utils); 19 const utils = require(global.utils);
18 const RegService = require('../models/reg-service'); 20 const RegService = require('../models/reg-service');
19 const AuthHelper = require('../models/auth-helper'); 21 const AuthHelper = require('../models/auth-helper');
@@ -122,21 +124,10 @@ const local = { @@ -122,21 +124,10 @@ const local = {
122 req.session.captchaValidCount = 5; 124 req.session.captchaValidCount = 5;
123 } 125 }
124 126
125 - // 先清除cookie  
126 - // res.clearCookie('LE' + md5('_LOGIN_EXPIRE'), {  
127 - // domain: 'yohobuy.com'  
128 - // });  
129 -  
130 - // 设置登录有效时间30分钟, 防机器刷,cache不稳定,改为cookie  
131 - // res.cookie('LE' + md5('_LOGIN_EXPIRE'), (new Date()).getTime() / 1000 + 1800);  
132 -  
133 - // 170406 账户密码方式登录可以选择是否开启验证码,默认开关是关闭状态,此时开启验证码,开关开启,无需验证  
134 - let captchaShow = _.get(req.app.locals.wap, 'close.loginValidation', false);  
135 -  
136 res.render('login', { 127 res.render('login', {
137 width750: true, 128 width750: true,
138 loginIndex: true, // 模板中使用JS的标识 129 loginIndex: true, // 模板中使用JS的标识
139 - captchaShow: !captchaShow, // 170306 因为暴力破解密码问题,要求每次都展示验证码 130 + captchaShow: req.yoho.captchaShow,
140 backUrl: 'javascript:history.go(-1)', // eslint-disable-line 131 backUrl: 'javascript:history.go(-1)', // eslint-disable-line
141 showHeaderImg: true, // 控制显示头部图片 132 showHeaderImg: true, // 控制显示头部图片
142 isPassportPage: true, // 模板中模块标识 133 isPassportPage: true, // 模板中模块标识
@@ -166,22 +157,11 @@ const local = { @@ -166,22 +157,11 @@ const local = {
166 req.session.captchaValidCount = 5; 157 req.session.captchaValidCount = 5;
167 } 158 }
168 159
169 - // 先清除cookie  
170 - // res.clearCookie('LE' + md5('_LOGIN_EXPIRE'), {  
171 - // domain: 'yohobuy.com'  
172 - // });  
173 -  
174 - // 设置登录有效时间30分钟, 防机器刷,cache不稳定,改为cookie  
175 - // res.cookie('LE' + md5('_LOGIN_EXPIRE'), (new Date()).getTime() / 1000 + 1800);  
176 -  
177 - // 170406 账户密码方式登录可以选择是否开启验证码,默认开关是关闭状态,此时开启验证码,开关开启,无需验证  
178 - let captchaShow = _.get(req.app.locals.wap, 'close.loginValidation', false);  
179 -  
180 res.render('international', { 160 res.render('international', {
181 width750: true, 161 width750: true,
182 backUrl: 'javascript:history.go(-1)', // eslint-disable-line 162 backUrl: 'javascript:history.go(-1)', // eslint-disable-line
183 loginInternational: true, // 模板中使用JS的标识 163 loginInternational: true, // 模板中使用JS的标识
184 - captchaShow: !captchaShow, // 170306 因为暴力破解密码问题,要求每次都展示验证码 164 + captchaShow: req.yoho.captchaShow,
185 isPassportPage: true, // 模板中模块标识 165 isPassportPage: true, // 模板中模块标识
186 headerText: '登录', 166 headerText: '登录',
187 areaCode: '+86', // 默认区号 167 areaCode: '+86', // 默认区号
@@ -211,6 +191,8 @@ const local = { @@ -211,6 +191,8 @@ const local = {
211 captchaShow: true 191 captchaShow: true
212 }; 192 };
213 193
  194 + cache.set(`loginErrorIp:${req.yoho.clientIp}`, true, 3600).catch(log.error);
  195 +
214 res.json(obj); 196 res.json(obj);
215 } else { 197 } else {
216 let refer = req.cookies.refer; 198 let refer = req.cookies.refer;
@@ -406,6 +388,36 @@ exports.user = function(req, res, next) { @@ -406,6 +388,36 @@ exports.user = function(req, res, next) {
406 res.jsonp(result); 388 res.jsonp(result);
407 }; 389 };
408 390
  391 +/**
  392 + * 中间件
  393 + * 根据用户登录是否成功决定是否展示验证码
  394 + */
  395 +exports.loginShowCaptchaByIp = function(req, res, next) {
  396 + // 总开关状态
  397 + req.yoho.captchaShow = !_.get(req.app.locals.wap, 'close.loginValidation', false);
  398 +
  399 + // 开关打开,不走任何验证逻辑
  400 + if (!req.yoho.captchaShow) {
  401 + return next();
  402 + } else {
  403 + req.yoho.captchaShow = false;
  404 + }
  405 +
  406 + co(function*() {
  407 + let hasErrorLog = yield cache.get(`loginErrorIp:${req.yoho.clientIp}`);
  408 +
  409 + log.info(`Pagerender clientip ${req.yoho.clientIp} status is ` + hasErrorLog);
  410 +
  411 + if (hasErrorLog) {
  412 + req.yoho.captchaShow = true;
  413 + }
  414 + next();
  415 + })().catch(function(e) {
  416 + req.yoho.captchaShow = true;
  417 + next();
  418 + });
  419 +};
  420 +
409 exports.common = common; 421 exports.common = common;
410 exports.local = local; 422 exports.local = local;
411 exports.wechat = wechat; 423 exports.wechat = wechat;
@@ -7,6 +7,9 @@ @@ -7,6 +7,9 @@
7 'use strict'; 7 'use strict';
8 const _ = require('lodash'); 8 const _ = require('lodash');
9 const config = global.yoho.config; 9 const config = global.yoho.config;
  10 +const co = Promise.coroutine;
  11 +const cache = global.yoho.cache;
  12 +const log = global.yoho.logger;
10 const geetest = require('./geetest'); 13 const geetest = require('./geetest');
11 const captcha = require('./captcha'); 14 const captcha = require('./captcha');
12 15
@@ -20,20 +23,44 @@ const check = (req, res, next) => { @@ -20,20 +23,44 @@ const check = (req, res, next) => {
20 return next(); 23 return next();
21 } 24 }
22 25
23 - // 170406 采用账号密码方式登录验证码可以配置关闭,默认开关是关闭状态,这时需要验证,开关开启,无需验证  
24 - if (_.get(req.app.locals.wap, 'close.loginValidation', false) && req.path === '/passport/login/auth') {  
25 - return next();  
26 - } 26 + // 默认取配置总开关来决定是否展示验证码
  27 + req.yoho.captchaShow = !_.get(req.app.locals.wap, 'close.loginValidation', false);
27 28
28 - // 使用极验证  
29 - let useGeetest = !_.get(req.app.locals.wap, 'geetest.validation', false); 29 + co(function* () {
  30 + // 如果是账号密码登录,那么需要检查是否登录失败过,登录失败过展示验证码
  31 + if (req.path === '/passport/login/auth') {
  32 + let hasErrorLog = yield cache.get(`loginErrorIp:${req.yoho.clientIp}`);
30 33
31 - // 某次请求极验证调用注册失败,强制使用自有图形验证码  
32 - if (req.session.useYohoCaptcha) {  
33 - useGeetest = false;  
34 - } 34 + log.info(`Check clientip ${req.yoho.clientIp} status is ` + hasErrorLog);
  35 +
  36 + if (hasErrorLog) {
  37 + req.yoho.captchaShow = true;
  38 + } else {
  39 + req.yoho.captchaShow = false;
  40 + }
  41 + }
  42 +
  43 + return req.yoho.captchaShow;
  44 + })().catch(function() {
  45 + // memcache 不可用,展示验证码
  46 + req.yoho.captchaShow = true;
  47 + return req.yoho.captchaShow;
  48 + }).then(function() {
  49 + // 不是账号密码登录,直接根据配置总开关决定是否需要展示验证码
  50 + if (!req.yoho.captchaShow) {
  51 + return next();
  52 + }
  53 +
  54 + // 使用极验证
  55 + let useGeetest = !_.get(req.app.locals.wap, 'geetest.validation', false);
  56 +
  57 + // 某次请求极验证调用注册失败,强制使用自有图形验证码
  58 + if (req.session.useYohoCaptcha) {
  59 + useGeetest = false;
  60 + }
35 61
36 - return (useGeetest ? geetest : captcha).validate(req, res, next); 62 + return (useGeetest ? geetest : captcha).validate(req, res, next);
  63 + });
37 }; 64 };
38 65
39 /** 66 /**
@@ -39,10 +39,21 @@ router.get('/emailback.html', back.indexEmailPage); @@ -39,10 +39,21 @@ router.get('/emailback.html', back.indexEmailPage);
39 router.get('/passport/signout/index', login.common.clearCookie, login.local.logout); 39 router.get('/passport/signout/index', login.common.clearCookie, login.local.logout);
40 40
41 // 登录页面 41 // 登录页面
42 -router.get('/passport/login', validateCode.load,  
43 - login.common.beforeLogin, login.common.clearCookie, login.local.loginPage);  
44 -router.get('/passport/international', validateCode.load,  
45 -login.common.beforeLogin, login.common.clearCookie, login.local.international); 42 +router.get('/passport/login',
  43 + validateCode.load,
  44 + login.common.beforeLogin,
  45 + login.common.clearCookie,
  46 + login.loginShowCaptchaByIp,
  47 + login.local.loginPage
  48 +);
  49 +
  50 +router.get('/passport/international',
  51 + validateCode.load,
  52 + login.common.beforeLogin,
  53 + login.common.clearCookie,
  54 + login.loginShowCaptchaByIp,
  55 + login.local.international
  56 +);
46 57
47 // 本地登录 58 // 本地登录
48 router.post('/passport/login/auth', validateCode.check, login.local.login); 59 router.post('/passport/login/auth', validateCode.check, login.local.login);
@@ -123,6 +123,8 @@ const selectHotrank = (yhChannel, gender, sort, tabId, limit, page, notab) => { @@ -123,6 +123,8 @@ const selectHotrank = (yhChannel, gender, sort, tabId, limit, page, notab) => {
123 } 123 }
124 124
125 return formData; 125 return formData;
  126 + } else {
  127 + return {};
126 } 128 }
127 129
128 }); 130 });
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 "xml2js": "^0.4.17", 50 "xml2js": "^0.4.17",
51 "yoho-express-session": "^2.0.0", 51 "yoho-express-session": "^2.0.0",
52 "yoho-md5": "^2.0.0", 52 "yoho-md5": "^2.0.0",
53 - "yoho-node-lib": "=0.2.16", 53 + "yoho-node-lib": "=0.2.17",
54 "yoho-zookeeper": "^1.0.8" 54 "yoho-zookeeper": "^1.0.8"
55 }, 55 },
56 "devDependencies": { 56 "devDependencies": {
@@ -14,7 +14,6 @@ let $account = $('#account'), @@ -14,7 +14,6 @@ let $account = $('#account'),
14 $ways = $('#retrive-pwd-ways'), 14 $ways = $('#retrive-pwd-ways'),
15 15
16 $captcha = $('#js-img-check'), 16 $captcha = $('#js-img-check'),
17 - useVerify = $captcha.data('userverify'), // 170406 是否使用验证  
18 17
19 accPass = false, 18 accPass = false,
20 pwdPass = false; 19 pwdPass = false;
@@ -26,16 +25,14 @@ let trim = $.trim; @@ -26,16 +25,14 @@ let trim = $.trim;
26 let showErrTip = tip.show; 25 let showErrTip = tip.show;
27 26
28 27
29 -let validate = {};  
30 -  
31 -if (useVerify) {  
32 - validate = new Validate($captcha, {  
33 - useREM: {  
34 - rootFontSize: 40,  
35 - picWidth: 150  
36 - }  
37 - }); 28 +let validate = new Validate($captcha, {
  29 + useREM: {
  30 + rootFontSize: 40,
  31 + picWidth: 150
  32 + }
  33 +});
38 34
  35 +if ($captcha.data('userverify')) {
39 validate.init(); 36 validate.init();
40 } 37 }
41 38
@@ -100,8 +97,13 @@ function loginAuth(params, acc) { @@ -100,8 +97,13 @@ function loginAuth(params, acc) {
100 location.href = res.href; 97 location.href = res.href;
101 $loginBtn.text('登录成功'); 98 $loginBtn.text('登录成功');
102 } else { 99 } else {
103 - if (useVerify && data.captchaShow) {  
104 - ((data.changeCaptcha && validate.type !== 2) && validate.refresh()); 100 + $captcha.data('userverify', data.captchaShow);
  101 + if (data.captchaShow) {
  102 + if (validate.atWorking) {
  103 + ((data.changeCaptcha && validate.type !== 2) && validate.refresh());
  104 + } else {
  105 + validate.init();
  106 + }
105 } 107 }
106 108
107 showErrTip(data.message); 109 showErrTip(data.message);
@@ -161,7 +163,7 @@ $loginBtn.on('touchstart', function() { @@ -161,7 +163,7 @@ $loginBtn.on('touchstart', function() {
161 password: pwd 163 password: pwd
162 }; 164 };
163 165
164 - if (useVerify) { 166 + if ($captcha.data('userverify')) {
165 validate.getResults().then((result) => { 167 validate.getResults().then((result) => {
166 $loginBtn.text('正在登录...').addClass('disable'); 168 $loginBtn.text('正在登录...').addClass('disable');
167 169