Authored by 王水玲

短信验证登录

... ... @@ -18,6 +18,7 @@ const helpers = global.yoho.helpers;
const log = global.yoho.logger;
const config = global.yoho.config;
const cache = global.yoho.cache;
const crypto = global.yoho.crypto;
const LoginService = require('../models/login-service');
const PassportHelper = require('../models/passport-helper');
const safeRedirect = require('../../../doraemon/middleware/safe-redirect').safeRedirect;
... ... @@ -127,6 +128,11 @@ const local = {
let loginCountryCode = '+' + _.trim(req.query.bindArea || '86');
let countries = PassportHelper.getCountry();
let defaultCountryName = '';
let account = req.cookies.account || '';
if (account) {
account = crypto.decrypt('yoho9646yoho9646', account);
}
if (loginCountryCode) {
let area = countries.find((a) => {
... ... @@ -153,7 +159,7 @@ const local = {
qqLogin: helpers.urlFormat('/passport/autosign/qq'),
weiboLogin: helpers.urlFormat('/passport/autosign/sina'),
alipayLogin: helpers.urlFormat('/passport/autosign/alipay'),
bindMobile: loginMobile
bindMobile: loginMobile || account
},
module: 'passport',
page: 'login',
... ... @@ -182,6 +188,15 @@ const local = {
account: req.body.account,
password: req.body.password
}, req, res);
res.cookie('account', crypto.encryption('yoho9646yoho9646', req.body.account), {
domain: config.cookieDomain,
httpOnly: true
});
} else {
res.clearCookie('account', {
domain: config.cookieDomain
});
}
refer = !BlockRedirectFilter.test(decodeURI(refer)) && refer ? decodeURI(refer) : config.siteUrl;
... ... @@ -202,6 +217,10 @@ const local = {
req.session.reset();
const clearAll = (v, k) => {
if (k === 'account') {
return;
}
res.clearCookie(k, {
domain: config.cookieDomain
});
... ...
... ... @@ -54,6 +54,8 @@ let index = (req, res) => {
req.session._REG_EXPIRE = Date.now() + 1800000;
let refer = req.query.refer;
let mobile = req.query.mobile;
let area = req.query.area;
refer && res.cookie('refer', encodeURI(refer), {
domain: config.cookieDomain,
... ... @@ -67,7 +69,8 @@ let index = (req, res) => {
country: {
list: passportHelper.getCountry()
},
location: '+86',
location: area || '+86',
defaultMobile: mobile || '',
countryName: {
text: '中国'
},
... ...
... ... @@ -62,7 +62,7 @@
</div>
<div class="left sms-btn-wrap">
<input type="submit" id="sms-btn" class="btn sms-btn" value='获取短信验证码'/>
<input type="button" id="sms-btn" class="btn sms-btn" value='获取短信验证码'/>
</div>
</li>
... ...
... ... @@ -11,7 +11,7 @@
{{>select-list}}
<div id="phone" class="left phone relative">
<span id="country-code" class="country-code">{{location}}</span>
<input value="" id="phone-num" class="input phone-num" type="text" name="phoneNum"
<input value="{{defaultMobile}}" id="phone-num" class="input phone-num" type="text" name="phoneNum"
placeholder="Phone Number" autocomplete="off">
{{> err-tip}}
... ...
... ... @@ -12,25 +12,22 @@ var $phoneNumInput = $('#account'),
$imgCaptchaInput = $('#captcha'),
$smsCaptchaInput = $('#captcha-sms'),
$smsCodeWrap = $('.sms-code-wrap'),
$pwdWrap = $('.pwd-wrap'),
$captchaSmsTokenHideInput = $('#captcha-sms-token-hide'),
$loginBtn = $('#login-btn'),
$phone = $('#phone'),
$smsBtn = $('#sms-btn');
$smsBtn = $('#sms-btn'),
$regionCodeText = $('#country-code'),
$regionSelectList = $('#country-select-list'),
$regionSelectHeader = $('#country-select-header'),
$emailAutoComplete = $('#email-autocomplete');
var $loginTip = $loginBtn.siblings('.login-fail-tip'),
ep = new EventProxy();
var $regionCodeText = $('#country-code'),
$regionSelectList = $('#country-select-list'),
$regionSelectHeader = $('#country-select-header');
var $emailAutoComplete = $('#email-autocomplete');
var mailPhoneRegx = require('../common/mail-phone-regx');
var mailAc = require('../common/ac-email'); // 邮箱自动完成
var $remember = $('.remember-me');
var captchaUrl = '/passport/images?t='; // /passport/images?t=1454464125
var showCaptcha = false;
... ... @@ -69,7 +66,7 @@ function errTip(ele, msg) {
var $errTip = ele.next('.tips');
var $errMsg = $errTip.find('.content');
$errMsg.text(msg);
$errMsg.html(msg);
return $errTip.removeClass('hide');
}
... ... @@ -77,9 +74,19 @@ function hideTip(ele) {
return ele.next('.tips').addClass('hide');
}
// 获取区域号
function getArea() {
return $regionCodeText.text().replace('+', '');
}
// 获取用户输入的手机号
function getMoblie() {
return $.trim($phoneNumInput.val());
}
// 验证账户名
function validateAccountLocal() {
var phoneNum = $.trim($phoneNumInput.val()),
var phoneNum = getMoblie(),
regionCode = $regionCodeText.text();
if (phoneNum !== '') {
... ... @@ -119,14 +126,14 @@ function validateAccountAsync(url) {
type: 'POST',
url: url,
data: {
phoneNum: $phoneNumInput.val(),
area: $regionCodeText.text().replace('+', '')
phoneNum: getMoblie(),
area: getArea()
}
}).then(function(data) {
if (data.code && data.code === 200) {
return true;
} else {
errTip($phoneNumInput, '账号不存在');
errTip($phoneNumInput, data.message);
return false;
}
});
... ... @@ -204,6 +211,7 @@ function validateCaptchaLocal() {
}
}
// 异步验证图片验证码
function validateCaptchaImgAsync() {
return $.ajax({
url: '/passport/images/check',
... ... @@ -221,7 +229,12 @@ function validateCaptchaImgAsync() {
});
}
// 整合本地和异步验证信息
function validateCaptchaImg() {
if ($captchaWrap.hasClass('hide')) {
return true;
}
return (function() {
var defer = $.Deferred(); // eslint-disable-line
... ... @@ -255,50 +268,13 @@ function showAccountErrTimes() {
$imgCaptchaInput.val('');
}
// 登录
function login() {
return $.ajax({
url: '/passport/login/auth',
type: 'POST',
data: {
areaCode: $regionCodeText.text().replace('+', ''),
account: $.trim($phoneNumInput.val()),
password: currLoginType === 'PasswordLogin' ? $.trim($passwordInput.val()) : $captchaSmsTokenHideInput.val(), // eslint-disable-line
captcha: $.trim($imgCaptchaInput.val()),
isRemember: $remember.hasClass('checked') ? true : false,
loginType: currLoginType
},
success: function(res) {
if (res.code === 200) {
if (res.data) {
// 防止data.data为undefined时下行语句执行出错而导致脚本不能走到complete去处理authing
location.href = res.data.refer;
}
} else {
if (res.data.errorType === 'captcha') {
$imgCaptchaInput.val('');
} else {
$loginTip.removeClass('hide').children('em').html(res.message);
$passwordInput.val('');
}
// 验证错误次数
if (res.data && res.data.needCaptcha) {
showAccountErrTimes();
}
}
}
});
}
// 登录次数限制接口
function throttle() {
return $.ajax({
url: '/passport/login/account',
type: 'GET',
data: {
account: $.trim($phoneNumInput.val())
account: getMoblie()
}
});
}
... ... @@ -329,25 +305,6 @@ function validate() {
});
}
// 全部的本地验证
function loginAsync() {
// return validateAccount().then(function() {
// var defer = $.Deferred(); // eslint-disable-line
//
// if (validateCaptchaLocal() && validatePasswordLocal()) {
// defer.resolve(true);
// } else {
// defer.reject(false);
// }
//
// return defer.promise();
// }).then(function() {
// return login();
// });
return login();
}
// 邮箱自动补全
mailAc($phoneNumInput, function() {
});
... ... @@ -397,17 +354,16 @@ $regionSelectHeader.on('click', function() {
changeHeader();
});
// 密码
// 密码失去焦点后校验
$passwordInput.on('blur', function() {
$passwordInput.removeClass('focus');
validatePasswordLocal();
}).on('focus', function() {
$passwordInput.addClass('focus');
hideTip($passwordInput);
});
// 图形验证码
// 图形验证码失去焦点|获取焦点的校验
$imgCaptchaInput.on('blur', function() {
$imgCaptchaInput.removeClass('focus');
validateCaptchaImg();
... ... @@ -464,9 +420,8 @@ ep.tail('phone', 'captcha', 'smsCode', function(phoneAuth, captchaAuth, smsCodeA
}
});
// 如果密码登录的图形验证码隐藏状态就直接通过校验
if (currLoginType === 'PasswordLogin') {
// 如果密码登录的图形验证码隐藏状态就直接通过校验
if ($captchaWrap.hasClass('hide')) {
ep.emit('captcha', true);
}
... ... @@ -496,53 +451,8 @@ ep.on('smsCode', function(auth) {
}
});
// 登录
$loginBtn.on('click', function() {
if ($loginBtn.hasClass('auth_ok')) {
return;
}
loginAsync();
});
// Enter登录
$('input.va').on('keypress', function(e) {
if (e.which === 13) {
loginAsync();
}
});
$('.login-page .switch > div').off().on('click', function() {
var type = $(this).data('type');
currLoginType = type;
if (type === 'PasswordLogin') {
$('.pwd-wrap').toggleClass('hide');
$('.sms-code-wrap').toggleClass('hide');
if (!showCaptcha) {
$('.captcha-wrap').addClass('hide');
ep.emit('captcha', true);
} else {
refreshCaptcha();
}
} else if (type === 'SMSLogin') {
$('.pwd-wrap').toggleClass('hide');
$('.sms-code-wrap').toggleClass('hide');
$('.captcha-wrap').removeClass('hide');
hideTip($imgCaptchaInput);
ep.emit('captcha', false);
$smsCaptchaInput.val('');
refreshCaptcha();
}
$('.login-page .switch > div').removeClass('selected');
$(this).addClass('selected');
});
/** ***********************************************手机验证码登录*********************************************/
// 倒计时 60秒
function disable60sSendSmsBtn() {
secondCount -= 1;
if (secondCount < 0) {
... ... @@ -558,18 +468,19 @@ function disable60sSendSmsBtn() {
}
}
// 发送短信验证码
function sendCaptchaSmsAsync() {
return $.ajax({
type: 'POST',
url: '/passport/login/sms/send',
data: {
area: $regionCodeText.text().replace('+', ''),
mobile: $.trim($phoneNumInput.val())
area: getArea(),
mobile: getMoblie()
}
});
}
// 短信验证验证码
// 验证码输入本地校验
function validateCaptchaSmsLocal() {
var smsCaptcha = $.trim($smsCaptchaInput.val());
var length = smsCaptcha.length;
... ... @@ -586,20 +497,20 @@ function validateCaptchaSmsLocal() {
}
}
// 异步验证短信验证码是否存在
// 异步校验短信验证码是否存在 Note: 这里的验证码只能成功验证一次,十分钟内有效
function validateCaptchaSmsAsync() {
var smsToken = $.trim($captchaSmsTokenHideInput.val());
if (isSmsCheckedSuccessFlag && smsToken !== '') {
return false; // eslint-disable-line
return $.Deferred().resolve(true).promise(); // eslint-disable-line
}
return $.ajax({
url: '/passport/login/sms/auth',
type: 'POST',
data: {
area: $regionCodeText.text().replace('+', ''),
mobile: $.trim($phoneNumInput.val()),
area: getArea(),
mobile: getMoblie(),
code: $.trim($smsCaptchaInput.val())
}
}).then(function(data) {
... ... @@ -645,12 +556,51 @@ function validateCaptchaSms() {
});
}
// 切换登录方式
function changeLoginType() {
var type = $(this).data('type');
if ($(this).hasClass('selected')) {
return false;
}
currLoginType = type;
if (type === 'PasswordLogin') {
$pwdWrap.removeClass('hide');
$smsCodeWrap.addClass('hide');
if (!showCaptcha) {
$captchaWrap.addClass('hide');
ep.emit('captcha', true);
} else {
refreshCaptcha();
}
hideTip($smsCaptchaInput);
} else if (type === 'SMSLogin') {
$pwdWrap.addClass('hide');
$smsCodeWrap.removeClass('hide');
$captchaWrap.removeClass('hide');
ep.emit('captcha', false);
$smsCaptchaInput.val('');
hideTip($passwordInput);
refreshCaptcha();
}
hideTip($phoneNumInput);
hideTip($imgCaptchaInput);
$(this).siblings().removeClass('selected');
$(this).addClass('selected');
}
$('.login-page .switch > div').off().on('click', changeLoginType);
// 短信验证码发送按钮
$smsBtn.on('click', function() {
// 已在发送短信时间范围内
if ($smsBtn.hasClass('second-progress')) {
return;
}
validateAccount()
.then(validateCaptchaImg)
.then(function() {
... ... @@ -669,3 +619,93 @@ $smsCaptchaInput.on('blur', function() {
});
/****************************************************登录事件********************************************/
// 登录
function login() {
return $.ajax({
url: '/passport/login/auth',
type: 'POST',
data: {
areaCode: getArea(),
account: getMoblie(),
password: currLoginType === 'PasswordLogin' ? $.trim($passwordInput.val()) : $captchaSmsTokenHideInput.val(), // eslint-disable-line
captcha: $.trim($imgCaptchaInput.val()),
isRemember: $remember.hasClass('checked') ? true : false,
loginType: currLoginType
},
success: function(res) {
if (res.code === 200) {
if (res.data) {
// 防止data.data为undefined时下行语句执行出错而导致脚本不能走到complete去处理authing
location.href = res.data.refer;
}
} else {
if (res.data.errorType === 'captcha') {
$imgCaptchaInput.val('');
} else {
$loginTip.removeClass('hide').children('em').html(res.message);
$passwordInput.val('');
}
// 验证错误次数
if (res.data && res.data.needCaptcha) {
showAccountErrTimes();
}
}
}
});
}
// 全部的本地验证-- 密码登录
function loginAsync() {
return validateAccount()
.then(validateCaptchaImg)
.then(function() {
var defer = $.Deferred(); // eslint-disable-line
if (validatePasswordLocal()) {
defer.resolve(true);
} else {
defer.reject(false);
}
return defer.promise();
}).then(function() {
return login();
});
}
// 全部的本地验证-- 短信验证登录
function smsLoginAsync() {
return validateAccount()
.then(validateCaptchaImg)
.then(validateCaptchaSms)
.then(function() {
return login();
});
}
// 登录
$loginBtn.on('click', function() {
if ($loginBtn.hasClass('auth_ok')) {
return;
}
if (currLoginType === 'PasswordLogin') {
loginAsync();
} else {
smsLoginAsync();
}
});
// Enter登录
$('input.va').on('keypress', function(e) {
if (e.which === 13) {
if (currLoginType === 'PasswordLogin') {
loginAsync();
} else {
smsLoginAsync();
}
}
});
... ...
... ... @@ -58,7 +58,6 @@ function hideTip(ele) {
}
setTimeout(function() {
$phoneNumInput.val('');
$smsCaptchaInput.val('');
$passwordInput.val('');
$imgCaptchaInput.val('');
... ...
... ... @@ -29,6 +29,17 @@
.phone {
@mixin phone;
.rectangle {
width: auto;
min-width: 100%;
white-space: nowrap;
padding-right: 15px;
a {
padding-left: 5px;
}
}
}
.input {
... ...