Authored by zhangxiaoru

防刷

@@ -12,6 +12,8 @@ const RegService = require('../models/reg-service'); @@ -12,6 +12,8 @@ const RegService = require('../models/reg-service');
12 const BindService = require('../models/bind-service'); 12 const BindService = require('../models/bind-service');
13 const AuthHelper = require('../models/auth-helper'); 13 const AuthHelper = require('../models/auth-helper');
14 const _ = require('lodash'); 14 const _ = require('lodash');
  15 +const config = global.yoho.config;
  16 +const moment = require('moment');
15 17
16 const Sources = { 18 const Sources = {
17 qq: 'QQ', 19 qq: 'QQ',
@@ -87,32 +89,54 @@ const bind = { @@ -87,32 +89,54 @@ const bind = {
87 let openId = req.body.openId; 89 let openId = req.body.openId;
88 let areaCode = req.body.areaCode || '86'; 90 let areaCode = req.body.areaCode || '86';
89 let sourceType = req.body.sourceType; 91 let sourceType = req.body.sourceType;
  92 + let verify = req.body.verify || '';
  93 + let testCode = req.body.yohobuy;
90 94
91 if (_.isNumber(parseInt(phoneNum, 0)) && openId && areaCode && sourceType) { 95 if (_.isNumber(parseInt(phoneNum, 0)) && openId && areaCode && sourceType) {
92 - BindService.bindCheck(phoneNum, openId, sourceType, areaCode).then(result => {  
93 - let data = {  
94 - code: result.code,  
95 - message: result.message,  
96 - data: {}  
97 - };  
98 -  
99 - if (result.code === 200) {  
100 - let nextUrl = helpers.urlFormat('/passport/bind/code', {  
101 - isReg: result.data.is_register, // esline-disable-line  
102 - openId: openId,  
103 - sourceType: sourceType,  
104 - areaCode: areaCode,  
105 - phoneNum: phoneNum  
106 - });  
107 -  
108 - data.data.isReg = result.data.is_register;  
109 - data.data.next = nextUrl; 96 + if (verify) {
  97 + let captcha = _.get(req, 'session.captcha');
  98 +
  99 + if ((captcha && verify.toString() === captcha) || (testCode === config.testCode)) {
  100 + BindService.bindCheck(phoneNum, openId, sourceType, areaCode).then(result => {
  101 + let data = {
  102 + code: result.code,
  103 + message: result.message,
  104 + data: {}
  105 + };
  106 +
  107 + if (result.code === 200) {
  108 + let nextUrl = helpers.urlFormat('/passport/bind/code', {
  109 + isReg: result.data.is_register, // esline-disable-line
  110 + openId: openId,
  111 + sourceType: sourceType,
  112 + areaCode: areaCode,
  113 + phoneNum: phoneNum
  114 + });
  115 +
  116 + data.data.isReg = result.data.is_register;
  117 + data.data.next = nextUrl;
  118 + } else {
  119 + data.data = result.data;
  120 + }
  121 +
  122 + res.json(data);
  123 + }).catch(next);
110 } else { 124 } else {
111 - data.data = result.data; 125 + let jsonData = {
  126 + code: 400,
  127 + message: '请将图片旋转到正确位置'
  128 + };
  129 +
  130 + if (req.session.captchaValidCount === 0) {
  131 + req.session.captcha = null; // 验证码 用过就扔
  132 + jsonData.changeCaptcha = true;
  133 + }
  134 +
  135 + return res.json(jsonData);
112 } 136 }
113 137
114 - res.json(data);  
115 - }).catch(next); 138 + _.set(req.session, 'captcha', null);
  139 + }
116 } else { 140 } else {
117 res.json({ 141 res.json({
118 code: 400, 142 code: 400,
@@ -122,6 +146,40 @@ const bind = { @@ -122,6 +146,40 @@ const bind = {
122 } 146 }
123 }, 147 },
124 148
  149 + //防刷
  150 + sendBefore: (req, res, next) => {
  151 + let count = _.get(req.session, 'bind.count');
  152 + let interval = _.get(req.session, 'bind.interval');
  153 +
  154 + let now = Date.now();
  155 +
  156 + // // 重发次数用完了, 会冻结5min
  157 + // // 1. 过了冻结期, count 重设为 5次
  158 + // // 2. 没过冻结期, end
  159 + // // 没有用完, 判断是否请求太频繁
  160 + let during = moment.duration(interval - now, 'ms').minutes();
  161 + let message = `请${during}分钟后再试`;
  162 +
  163 + if (!count) {
  164 + if (interval > now) {
  165 + return res.json({
  166 + code: 400,
  167 + message: message,
  168 + during: Math.ceil((interval - now) / 1000)
  169 + });
  170 + } else {
  171 + _.set(req.session, 'bind.count', 5);
  172 + }
  173 + } else if (interval > now) {
  174 + return res.json({
  175 + code: 429,
  176 + message: message
  177 + });
  178 + }
  179 +
  180 + next();
  181 + },
  182 +
125 sendBindMsg: (req, res, next) => { 183 sendBindMsg: (req, res, next) => {
126 let phoneNum = req.body.phoneNum; 184 let phoneNum = req.body.phoneNum;
127 let areaCode = req.body.areaCode; 185 let areaCode = req.body.areaCode;
@@ -129,6 +187,24 @@ const bind = { @@ -129,6 +187,24 @@ const bind = {
129 if (req.xhr && _.isNumber(parseInt(phoneNum, 0)) && areaCode) { 187 if (req.xhr && _.isNumber(parseInt(phoneNum, 0)) && areaCode) {
130 BindService.sendBindMsg(areaCode, phoneNum).then(result => { 188 BindService.sendBindMsg(areaCode, phoneNum).then(result => {
131 if (result && result.code) { 189 if (result && result.code) {
  190 +
  191 + if (result.code === 200) {
  192 +
  193 + _.set(req.session, 'bind.area', areaCode);
  194 + _.set(req.session, 'bind.mobile', phoneNum);
  195 +
  196 + --req.session.bind.count;
  197 +
  198 + if (!req.session.bind.count) {
  199 + _.set(req.session, 'bind.interval', Date.now() + 5 * 60 * 1000);
  200 + } else {
  201 + _.set(req.session, 'bind.interval', Date.now() + 60 * 1000);
  202 + }
  203 +
  204 + // res.json(result);
  205 + // return;
  206 + }
  207 +
132 res.json(result); 208 res.json(result);
133 } else { 209 } else {
134 res.json({ code: 400, message: '', data: '' }); 210 res.json({ code: 400, message: '', data: '' });
@@ -77,7 +77,9 @@ router.get('/login/alipay/callback', login.alipay.callback); @@ -77,7 +77,9 @@ router.get('/login/alipay/callback', login.alipay.callback);
77 router.get('/passport/bind/index', bind.indexPage); 77 router.get('/passport/bind/index', bind.indexPage);
78 router.post('/passport/bind/bindCheck', bind.bindCheck); 78 router.post('/passport/bind/bindCheck', bind.bindCheck);
79 router.get('/passport/bind/code', bind.codePage); 79 router.get('/passport/bind/code', bind.codePage);
80 -router.post('/passport/bind/sendBindMsg', bind.sendBindMsg); 80 +router.post('/passport/bind/sendBindMsg',
  81 + bind.sendBefore,
  82 + bind.sendBindMsg);
81 router.post('/passport/bind/bindMobile', bind.bindMobile); 83 router.post('/passport/bind/bindMobile', bind.bindMobile);
82 84
83 router.post('/passport/bind/relateMobile', bind.relateMobile); 85 router.post('/passport/bind/relateMobile', bind.relateMobile);
@@ -42,7 +42,6 @@ function nextStep(url, mobileNo, areaCode) { @@ -42,7 +42,6 @@ function nextStep(url, mobileNo, areaCode) {
42 42
43 requested = true; 43 requested = true;
44 $btnNext.addClass('disable').html('绑定中...'); 44 $btnNext.addClass('disable').html('绑定中...');
45 -  
46 $.ajax({ 45 $.ajax({
47 type: 'POST', 46 type: 'POST',
48 url: '/passport/bind/sendBindMsg', 47 url: '/passport/bind/sendBindMsg',
@@ -112,12 +111,11 @@ $btnNext.on('touchstart', function() { @@ -112,12 +111,11 @@ $btnNext.on('touchstart', function() {
112 phoneNum: pn, 111 phoneNum: pn,
113 openId: openId, 112 openId: openId,
114 sourceType: sourceType, 113 sourceType: sourceType,
115 - nickname: nickname 114 + nickname: nickname,
  115 + verify: verify
116 }, 116 },
117 success: function(res) { 117 success: function(res) {
118 118
119 - // console.log(res);  
120 -  
121 // res : { 119 // res : {
122 // code: 'xxx', 120 // code: 'xxx',
123 // data: { 121 // data: {
@@ -5,6 +5,8 @@ @@ -5,6 +5,8 @@
5 */ 5 */
6 var $ = require('yoho-jquery'); 6 var $ = require('yoho-jquery');
7 7
  8 +require('js/common');
  9 +
8 module.exports = function(useInRegister, useForBind, useForRelate) { 10 module.exports = function(useInRegister, useForBind, useForRelate) {
9 var $captcha = $('#captcha'), 11 var $captcha = $('#captcha'),
10 $btnNext = $('#btn-next'), 12 $btnNext = $('#btn-next'),
@@ -79,8 +81,8 @@ module.exports = function(useInRegister, useForBind, useForRelate) { @@ -79,8 +81,8 @@ module.exports = function(useInRegister, useForBind, useForRelate) {
79 }); 81 });
80 } 82 }
81 83
82 - function countDown() {  
83 - var count = 59, 84 + function countDown(during) {
  85 + var count = during || 59,
84 itime; 86 itime;
85 87
86 itime = setInterval(function() { 88 itime = setInterval(function() {
@@ -89,6 +91,11 @@ module.exports = function(useInRegister, useForBind, useForRelate) { @@ -89,6 +91,11 @@ module.exports = function(useInRegister, useForBind, useForRelate) {
89 clearInterval(itime); 91 clearInterval(itime);
90 } else { 92 } else {
91 $captchaTip.text('重新发送 (' + count-- + '秒)'); 93 $captchaTip.text('重新发送 (' + count-- + '秒)');
  94 + window.setCookie('count', count);
  95 +
  96 + if (during && parseInt(during) !== 0) {
  97 + $captchaTip.addClass('disable');
  98 + }
92 } 99 }
93 }, 1000); 100 }, 1000);
94 } 101 }
@@ -121,6 +128,7 @@ module.exports = function(useInRegister, useForBind, useForRelate) { @@ -121,6 +128,7 @@ module.exports = function(useInRegister, useForBind, useForRelate) {
121 $captchaTip.text('重发验证码 (60秒)').addClass('disable'); 128 $captchaTip.text('重发验证码 (60秒)').addClass('disable');
122 countDown(); 129 countDown();
123 } else { 130 } else {
  131 + data.during && countDown(data.during);
124 132
125 // 验证码不正确,显示提示 133 // 验证码不正确,显示提示
126 showErrTip(data.message); 134 showErrTip(data.message);
@@ -148,5 +156,10 @@ module.exports = function(useInRegister, useForBind, useForRelate) { @@ -148,5 +156,10 @@ module.exports = function(useInRegister, useForBind, useForRelate) {
148 } 156 }
149 }); 157 });
150 158
151 - countDown(); 159 + if (window.cookie('count') && parseInt(window.cookie('count')) > 0) {
  160 + countDown(window.cookie('count'));
  161 + } else {
  162 + countDown();
  163 + }
152 }; 164 };
  165 +