Authored by htoooth

add login

... ... @@ -78,9 +78,9 @@ passport.use(new LocalStrategy({
let accountTimes = _.parseInt(times[1]) || 0;
let ipTimes = _.parseInt(times[2]) || 0;
if (accountTimes >= Infinity) {
if (accountTimes >= 10) {
done({message: '您的账号已被暂时锁定,请稍后再试'}, null);
} else if (ipTimes >= Infinity) {
} else if (ipTimes >= 100) {
done({message: '您尝试的次数过多,账号已被暂时锁定,请稍后再试'}, null);
} else {
return AuthHelper.signin(area, username, password, shoppingKey).then((result) => {
... ...
... ... @@ -16,7 +16,7 @@ const config = global.yoho.config;
const cache = global.yoho.cache;
const AuthHelper = require('../models/auth-helper');
const PassportHelper = require('../models/passport-helper');
const loginPage = `${config.siteUrl}/signin.html`;
const loginPage = `${config.siteUrl}/signin`;
// 第三方登录回调
function doPassportCallback(req, res, user) {
... ... @@ -122,8 +122,6 @@ const local = {
qqLogin: helpers.urlFormat('/passport/autosign/qq'),
weiboLogin: helpers.urlFormat('/passport/autosign/sina'),
alipayLogin: helpers.urlFormat('/passport/autosign/alipay'),
doubanLogin: helpers.urlFormat('/passport/autosign/douban'),
renrenLogin: helpers.urlFormat('/passport/autosign/renren'),
bindMobile: bindMobile
},
module: 'passport',
... ... @@ -156,11 +154,11 @@ const local = {
if (refer) {
refer = decodeURI(req.cookies.refer);
} else {
refer = `${config.siteUrl}/home`;
refer = `${config.siteUrl}`;
}
if (/sign|login/.test(refer)) {
refer = `${config.siteUrl}/home`;
refer = `${config.siteUrl}`;
}
user.session = refer;
user.href = refer;
... ...
... ... @@ -39,14 +39,6 @@ router.get('/login/qq/callback', login.qq.callback);
router.get('/autosign/alipay', login.common.beforeLogin, login.alipay.login);
router.get('/login/alipay/callback', login.alipay.callback);
// douban登录
router.get('/autosign/douban', login.common.beforeLogin, login.douban.login);
router.get('/autosign/doubanback', login.douban.callback);
// renren登录
router.get('/autosign/renren', login.common.beforeLogin, login.renren.login);
router.get('/login/renren/callback', login.renren.callback);
router.get('/login/account', login.common.needCaptcha);
// 第三方登录后绑定
... ...
... ... @@ -12,7 +12,7 @@
{{/each}}
</select>
<div id="phone" class="left phone">
<div id="phone" class="left phone needTip">
<span id="country-code" class="country-code">{{countryCode}}</span>
<input id="account" class="account input phone-num va" name="account" value="{{bindMobile}}"
type="text"
... ... @@ -21,14 +21,14 @@
</li>
<li class="clearfix">
<input id="password" class="input password va" name="password" type="password" placeholder="Password"
<input id="password" class="input password va needTip" name="password" type="password"
placeholder="Password"
autocomplete="off" maxlength="20">
<span id="caps-lock" class="caps-lock hide">大写状态开启</span>
</li>
<li class="clearfix captcha-wrap hide">
<input id="captcha" class="input va captcha" type="text" name="captcha" placeholder="图形验证码"
<input id="captcha" class="input va captcha needTip" type="text" name="captcha" placeholder="图形验证码"
autocomplete="off" maxlength="4">
<div class="left captcha-component">
... ... @@ -38,6 +38,11 @@
</li>
<li class="clearfix">
<span class="left login-fail-tip hide">
<span class="'iconfont">&#xe608;</span>
<em></em>
</span>
<a id="login-btn" class="btn login-btn">登录</a>
</li>
... ... @@ -55,13 +60,13 @@
<li class="clearfix third-party-login">
<a href="{{weixinLogin}}">
<span class="iconfont weixin">&#xe622;</span>
<span class="iconfont weixin">&#xe642;</span>
</a>
<a href="{{qqLogin}}">
<span class="iconfont qq">&#xe626;</span>
<span class="iconfont qq">&#xe641;</span>
</a>
<a href="{{weiboLogin}}">
<span class="iconfont weibo">&#xe62e;</span>
<span class="iconfont weibo">&#xe640;</span>
</a>
<a href="{{alipayLogin}}">
<span class="iconfont alipay">&#xe63f;</span>
... ... @@ -78,6 +83,11 @@
</span>
</li>
<div class="tips hide">
<div class="triangle"></div>
<div class="rectangle"></div>
</div>
</ul>
<input id="country-code-hide" name="countryCode" type="hidden" value="{{countryCode}}">
{{/ passport}}
... ...
... ... @@ -26,9 +26,9 @@ module.exports = {
useOneapm: false,
useCache: false,
memcache: {
master: ['192.168.102.163:11213'],
slave: ['192.168.102.163:11213'],
session: ['192.168.102.161:11213'],
master: ['192.168.102.222:11213'],
slave: ['192.168.102.222:11213'],
session: ['192.168.102.222:11213'],
timeout: 1000,
retries: 0
},
... ...
... ... @@ -4,6 +4,7 @@
* @date: 2015/12/11
*/
var $ = require('yoho-jquery');
var EventProxy = require('../common/eventproxy');
var $account = $('#account'),
$password = $('#password'),
... ... @@ -11,11 +12,8 @@ var $account = $('#account'),
$login = $('#login-btn'),
$phone = $('#phone');
var $accountTip = $phone.siblings('.err-tip'),
$passwordTip = $password.siblings('.err-tip'),
$captchaTip = $captcha.siblings('.err-tip'),
$loginTip = $login.siblings('.login-fail-tip'),
$capsLock = $('#caps-lock');
var $loginTip = $login.siblings('.login-fail-tip'),
ep = new EventProxy();
var $countryCodeEm = $('#country-code'),
$countryList = $('#country-list');
... ... @@ -38,70 +36,74 @@ var checkbox = {
unchecked: '&#xe601;'
};
var authing = false;
var emailAcTime;
var ERR_ACCOUNT_EMPTY = '请输入账号';
var $errTip = $('.tips');
var $errMsg = $errTip.find('.rectangle');
$captcha = $captchaWrap.find('#captcha');
$captchaTip = $captchaWrap.find('.err-tip');
require('../../plugins/tips');
require('yoho-jquery-placeholder');
function errTip(ele, msg) {
var topLeft = ele.offset();
$errMsg.text(msg);
return $errTip.css({
top: topLeft.top + ele.height() - 2,
left: topLeft.left,
width: ele.width() + 2,
height: ele.height
}).removeClass('hide');
}
// 验证账户名
function validateAccount() {
var pass = false,
account = $.trim($account.val()),
countryCode = $countryCodeEm.val(),
err;
function validateAccountLocal() {
var account = $.trim($account.val()),
countryCode = $countryCodeEm.val();
if (account !== '') {
if (/^[0-9]+$/.test(account)) {
// 不是11位
if (account.length !== 11) {
ep.emit('phone', false);
errTip($phone, '手机号码不正确,请重新输入');
return false;
}
// 如果是纯数字,则作为手机号码处理
if (countryCode !== '+86' ||
mailPhoneRegx.phoneRegx[countryCode].test(account)) {
pass = true;
ep.emit('phone', true);
return true;
} else {
pass = false;
err = '手机号码不正确,请重新输入';
ep.emit('phone', false);
errTip($phone, '手机号码不正确,请重新输入');
return false;
}
} else {
// 邮箱验证
if (mailPhoneRegx.emailRegx.test(account)) {
pass = true;
ep.emit('phone', true);
return true;
} else {
pass = false;
err = '邮箱格式不正确,请重新输入';
ep.emit('phone', false);
errTip($phone, '邮箱格式不正确,请重新输入');
return false;
}
}
} else {
err = ERR_ACCOUNT_EMPTY;
ep.emit('phone', false);
errTip($phone, '请输入账号');
return false;
}
if (pass) {
$accountTip.addClass('hide');
} else {
$accountTip.removeClass('hide').children('em').text(err);
}
return pass;
}
function disableTips() {
'use strict';
$phone.tips('hide');
}
function enableTips() {
'use strict';
$phone.tips('show', '× 账号不存在');
}
function tryUser() {
function validateAccountAsync() {
return $.ajax({
type: 'POST',
url: '/passport/login/user',
... ... @@ -109,179 +111,150 @@ function tryUser() {
phoneNum: $account.val(),
area: $countryCodeEm.val().replace('+', '')
}
}).then(function(data) {
if (data.code && data.code === 200) {
authing = false;
disableTips();
ep.emit('phone', true);
return true;
} else {
enableTips();
authing = true;
ep.emit('phone', false);
errTip($phone, '账号不存在');
return false;
}
});
}
function validateAccount() {
var defer = $.Deferred(); // eslint-disable-line
// 验证密码
function validatePassword() {
var pass = false,
password = $.trim($password.val()),
err;
if (password !== '') {
if (password.length < 6) {
err = '请输入长度为6-20字符的密码';
} else {
pass = true;
}
if (validateAccountLocal()) {
validateAccountAsync().then(function(result) {
defer.resolve(result);
});
} else {
err = '请输入密码';
defer.resolve(false);
}
if (pass) {
$passwordTip.addClass('hide');
} else {
$passwordTip.removeClass('hide').children('em').text(err);
}
return pass;
return defer.promise();
}
// 验证验证码
function validateCaptcha() {
var pass = false,
captcha = $.trim($captcha.val()),
err;
// 验证码不可见的时候不验证
if ($captchaWrap.is(':hidden')) {
return true;
}
if (captcha !== '') {
if (captcha.length !== 4) {
err = '请输入长度为4字符的验证码';
// 验证密码
function validatePasswordLocal() {
var password = $.trim($password.val());
var length = password.length;
if (length !== 0) {
if (length < 6) {
ep.emit('password', false);
errTip($password, '请输入长度为6-20字符的密码');
return false;
} else {
pass = true;
ep.emit('password', true);
return true;
}
} else {
err = '请输入验证码';
errTip($password, '请输入密码');
ep.emit('password', false);
return false;
}
if (pass) {
$captchaTip.addClass('hide');
} else {
$captchaTip.removeClass('hide').children('em').text(err);
}
return pass;
}
// 验证
function validate() {
var pass = true,
account = $.trim($account.val()),
password = $.trim($password.val());
if (account !== '') {
pass = validateAccount() && validatePassword() && validateCaptcha();
} else {
pass = false;
if (password === '') {
// 验证验证码
function validateCaptchaLocal() {
var captcha = $.trim($captcha.val());
var length = captcha.length;
// 账户名和密码都为空的情况下点击登陆,只在账户输入框后显示错误提示
$accountTip.addClass('both-error').removeClass('hide').children('em').text('请输入账户名和密码');
$passwordTip.addClass('hide');
} else {
$accountTip.removeClass('hide').children('em').text(ERR_ACCOUNT_EMPTY);
}
if ($captchaWrap.hasClass('hide')) {
ep.emit('captcha', true);
return;
}
return pass;
switch (length) {
case 0:
errTip($captcha, '请输入验证码');
ep.emit('captcha', false);
break;
case 4:
ep.emit('captcha', true);
break;
default:
errTip($captcha, '请输入长度为4字符的验证码');
ep.emit('captcha', false);
break;
}
}
// 密码错误次数,超过三次显示验证码
function vaAccountErrTimes() {
function showAccountErrTimes() {
$captchaWrap.removeClass('hide');
$captchaImg.attr('src', captchaUrl + $.now());
$captcha.val('');
$captchaWrap.removeClass('hide');
}
// 登录
function login() {
var pass = validate();
if (pass && authing === false) {
authing = true;
$.ajax({
url: '/passport/login/auth',
type: 'POST',
data: {
areaCode: $countryCodeEm.val().replace('+', ''),
account: $.trim($account.val()),
password: $.trim($password.val()),
captcha: $.trim($captcha.val()),
isRemember: $remember.hasClass('checked') ? true : false
},
success: function(res) {
if (res.code === 200) {
if (res.data) {
// 防止data.data为undefined时下行语句执行出错而导致脚本不能走到complete去处理authing
location.href = res.data.session;
}
$.ajax({
url: '/passport/login/auth',
type: 'POST',
data: {
areaCode: $countryCodeEm.val().replace('+', ''),
account: $.trim($account.val()),
password: $.trim($password.val()),
captcha: $.trim($captcha.val()),
isRemember: $remember.hasClass('checked') ? true : false
},
success: function(res) {
if (res.code === 200) {
if (res.data) {
// 防止data.data为undefined时下行语句执行出错而导致脚本不能走到complete去处理authing
location.href = res.data.session;
}
} else {
if (res.data.errorType === 'captcha') {
$captcha.val('');
} else {
if (res.data.errorType === 'captcha') {
$captchaTip.removeClass('hide').children('em').html(res.message);
$captcha.val('');
} else {
$loginTip.removeClass('hide').children('em').html(res.message);
$password.val('');
}
// 验证错误次数
if (res.data && res.data.needCaptcha) {
vaAccountErrTimes();
}
$loginTip.removeClass('hide').children('em').html(res.message);
$password.val('');
}
// 验证错误次数
if (res.data && res.data.needCaptcha) {
showAccountErrTimes();
}
},
complete: function() {
authing = false;
}
});
}
}
});
}
mailAc($account, function() {
if (validateAccount()) {
tryUser().then(function() {
return $.ajax({
url: '/passport/login/account',
type: 'GET',
data: {
account: $.trim($account.val())
}
});
}).then(function(res) {
'use strict';
if (res.data && res.data.needCaptcha) {
vaAccountErrTimes();
function validateUser() {
return $.ajax({
url: '/passport/login/account',
type: 'GET',
data: {
account: $.trim($account.val())
}
});
}
});
$account.on('keyup', function() {
'use strict';
var value = $.trim($(this).val());
$.when(validateAccount()).then(function(result) {
if (result) {
return $.when(validateUser());
} else {
return $.when(false);
}
}).then(function(res) {
if (!res) {
return;
}
if (value.length === 0) {
disableTips();
}
}).on('focus', function() {
if (res.data && res.data.needCaptcha) {
showAccountErrTimes();
}
});
});
$account.on('focus', function() {
$phone.addClass('focus');
}).on('blur', function() {
$phone.removeClass('focus');
... ... @@ -290,32 +263,16 @@ $account.on('keyup', function() {
$('[placeholder]').placeholder();
$countryList.change(function() {
'use strict';
var $this = $(this);
$countryCodeEm.text($this.val());
});
// 密码
$password.on('blur', function() {
$password.removeClass('focus');
validatePassword();
if ($capsLock.hasClass('hide')) {
return;
}
$capsLock.addClass('hide');
}).on('keypress', function(e) {
var code = e.which;
// CapsLock检测
if (code >= 65 && code <= 90) {
$capsLock.removeClass('hide');
return;
}
$capsLock.addClass('hide');
validatePasswordLocal();
$captcha.trigger('blur');
}).on('focus', function() {
$password.addClass('focus');
});
... ... @@ -323,7 +280,7 @@ $password.on('blur', function() {
// 验证码
$captcha.on('blur', function() {
$captcha.removeClass('focus');
validateCaptcha();
validateCaptchaLocal();
}).on('focus', function() {
$captcha.addClass('focus');
});
... ... @@ -360,8 +317,46 @@ $captchaWrap.on('click', '.change-captcha, .captcha-img', function() {
$captchaImg.attr('src', captchaUrl + $.now());
});
// 初始:只带账户名的页面,密码输入获得焦点
if (($account.val() !== '' || $account.val() === $account.attr('placeholder')) &&
$password.val() === '') {
$password.focus();
}
ep.tail('phone', 'password', 'captcha', function(phoneAuth, passwordAuth, captchaAuth) {
if (phoneAuth && passwordAuth && captchaAuth) {
$login.removeClass('auth_ok');
} else {
$login.addClass('auth_ok');
}
});
ep.on('phone', function(auth) {
if (auth) {
$errTip.addClass('hide');
}
});
ep.on('password', function(auth) {
if (auth) {
$errTip.addClass('hide');
}
});
ep.on('captcha', function(auth) {
if (auth && !$captchaWrap.hasClass('hide')) {
$errTip.addClass('hide');
}
});
// 登录
$login.on('click', login);
$login.on('click', function() {
if ($login.hasClass('auth_ok')) {
return;
}
login();
});
// Enter登录
$('input.va').on('keypress', function(e) {
... ... @@ -370,9 +365,3 @@ $('input.va').on('keypress', function(e) {
}
});
// 初始:只带账户名的页面,密码输入获得焦点
if (($account.val() !== '' || $account.val() === $account.attr('placeholder')) &&
$password.val() === '') {
$password.focus();
}
... ...
... ... @@ -13,10 +13,10 @@ var $registerPage = $('.register-page'),
$errTip = $('.tips'),
$registerBtn = $('#register-btn');
// $countDown = $('#count-down'),
// $successBtn = $('.success-btn'),
// countDown = 5,
// clearT;
// $countDown = $('#count-down'),
// $successBtn = $('.success-btn'),
// countDown = 5,
// clearT;
var $sendCaptcha = $('#send-captcha'),
caCount = 4,
... ... @@ -289,7 +289,6 @@ function validateRule(page, $element, callback) {
regionCode;
// 根据需求http://redmine.yoho.cn/issues/3117改成上边的正则
// 对应的错误提示语也改了,感觉要不了多久就会改回来
// pwdReg = /^([a-zA-Z0-9\-\+_!@\#$%\^&\*\(\)\:\;\.=\[\]\\\',\?]){6,20}$/gi;
... ... @@ -316,7 +315,7 @@ function validateRule(page, $element, callback) {
}
}
// 图形验证码校验
// 图形验证码校验
} else if ($element.hasClass('captcha')) {
if (val === '') {
validateResult[1].message = '请输入图形验证码';
... ... @@ -341,7 +340,7 @@ function validateRule(page, $element, callback) {
}
// 短信验证码校验
// 短信验证码校验
} else if ($element.hasClass('msg-captcha')) {
if (val === '') {
... ... @@ -366,7 +365,7 @@ function validateRule(page, $element, callback) {
}
}
// 密码校验
// 密码校验
} else if ($element.hasClass('pwd')) {
if (val === '') {
validateResult[3].message = '请输入密码';
... ... @@ -571,9 +570,9 @@ exports.init = function(page) {
}).blur(function() {
/* validateRule($(this), function() {
showErrTip();
showBorder(); // 显示红色边框
});*/
showErrTip();
showBorder(); // 显示红色边框
});*/
});
$regionSelect.change(function() {
... ...
... ... @@ -22,6 +22,7 @@
text-align: center;
width: $item-width;
color: $theme-color;
font-weight: bold;
}
.pwd-intensity-container {
... ...