Authored by htoooth

refactor code and add remember me.

... ... @@ -9,8 +9,8 @@
const _ = require('lodash');
const helpers = global.yoho.helpers;
const PassportHelper = require('../models/passport-helper');
const BindService = require('../models/bind-service');
const AuthHelper = require('../models/auth-helper');
const BindService = require('../models/bind-api');
const loginService = require('../models/login-service');
const Sources = {
qq: 'QQ',
... ... @@ -245,7 +245,7 @@ const bind = {
sourceType: sourceType + '_bind'
});
return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
return loginService.syncUserSession(result.data.uid, req, res).then(() => {
return {code: 200, message: result.message, data: {refer: refer}};
});
} else {
... ... @@ -271,7 +271,7 @@ const bind = {
sourceType: sourceType + '_bind'
});
return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
return loginService.syncUserSession(result.data.uid, req, res).then(() => {
return {code: 200, message: result.message, data: {refer: refer}};
});
} else {
... ...
... ... @@ -9,13 +9,17 @@ const _ = require('lodash');
const passport = require('passport');
const uuid = require('uuid');
const md5 = require('md5');
const Promise = require('bluebird');
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 AuthHelper = require('../models/auth-helper');
const loginService = require('../models/login-service');
const PassportHelper = require('../models/passport-helper');
const loginPageURL = `${config.siteUrl}/passport/login`;
// 第三方登录回调
... ... @@ -34,7 +38,7 @@ function doPassportCallback(req, res, user) {
}
if (user.openId && user.nickname) {
let signinByOpenID = AuthHelper.signinByOpenID(
let signinByOpenID = loginService.signinByOpenID(
user.nickname, user.openId, user.sourceType, shoppingKey, user.unionId);
return signinByOpenID.then((result) => {
... ... @@ -49,7 +53,7 @@ function doPassportCallback(req, res, user) {
refer: refer
});
} else if (result.code === 200 && result.data.uid) {
return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
return loginService.syncUserSession(result.data.uid, req, res).then(() => {
return refer;
});
}
... ... @@ -57,7 +61,7 @@ function doPassportCallback(req, res, user) {
return res.redirect(redirectTo);
});
} else {
res.redirect(loginPageURL);
return Promise.resolve(res.redirect(loginPageURL));
}
}
... ... @@ -96,7 +100,9 @@ const common = {
const local = {
loginPage: (req, res) => {
// 设置登录有效时间30分钟, 防机器刷,cache不稳定,改为cookie
res.cookie('LE' + md5('_LOGIN_EXPIRE'), (new Date()).getTime() / 1000 + 1800);
res.cookie('LE' + md5('_LOGIN_EXPIRE'), (new Date()).getTime() / 1000 + 1800, {
domain: config.cookieDomain
});
let bindMobile = _.trim(req.query.bindMobile || '');
let bindArea = '+' + _.trim(req.query.bindArea || '86');
... ... @@ -142,35 +148,37 @@ const local = {
}
});
} else {
let isRemember = req.body.isRemember;
let refer = req.cookies.refer;
if (isRemember) {
AuthHelper.rememberAccount({
area: req.body.areaCode || '86',
account: req.body.account,
password: req.body.password
}, req, res);
}
co(function * () {
let isRemember = req.body.isRemember === 'true';
let refer = req.cookies.refer;
if (refer) {
refer = decodeURI(req.cookies.refer);
} else {
refer = `${config.siteUrl}`;
}
if (isRemember) {
yield loginService.rememberAccount({
area: req.body.areaCode || '86',
account: req.body.account,
password: req.body.password
}, req, res);
}
if (/sign|login|passport/.test(refer)) {
refer = `${config.siteUrl}`;
}
if (refer) {
refer = decodeURI(req.cookies.refer);
} else {
refer = `${config.siteUrl}`;
}
AuthHelper.syncUserSession(user.uid, req, res).then(() => {
res.json({
code: 200,
data: {
refer: refer
}
if (/sign|login|passport/.test(refer)) {
refer = `${config.siteUrl}`;
}
yield loginService.syncUserSession(user.uid, req, res).then(() => {
res.json({
code: 200,
data: {
refer: refer
}
});
});
});
})();
}
})(req, res, next);
},
... ... @@ -188,10 +196,22 @@ const local = {
domain: config.cookieDomain
});
res.clearCookie('_SPK');
res.clearCookie('_g');
res.clearCookie('isRemember');
res.clearCookie('remem');
res.clearCookie('_SPK', {
domain: config.cookieDomain
});
res.clearCookie('_g', {
domain: config.cookieDomain
});
res.clearCookie('isRemember', {
domain: config.cookieDomain
});
res.clearCookie('remem', {
domain: config.cookieDomain
});
res.redirect(config.siteUrl);
}
};
... ...
... ... @@ -5,9 +5,9 @@
const _ = require('lodash');
const Promise = require('bluebird');
const passportHelper = require('../models/passport-helper');
const regService = require('../models/reg-service');
const regService = require('../models/reg-api');
const userService = require('../models/user-service');
const authHelper = require('../models/auth-helper');
const loginService = require('../models/login-service');
const config = require('../../../config/common');
let helpers = global.yoho.helpers;
... ... @@ -247,7 +247,7 @@ let mobileRegister = (req, res, next) => {
return res.json(data);
}
return authHelper.syncUserSession(regResult.data.uid, req, res).then(() => {
return loginService.syncUserSession(regResult.data.uid, req, res).then(() => {
return res.json({
code: 200,
message: '注册成功',
... ...
... ... @@ -30,7 +30,7 @@ app.engine('.hbs', hbs({
}));
require('./auth');
require('./models/login-auth-service');
app.use(passport.initialize());
app.use(passport.session());
... ...
'use strict';
const md5 = require('md5');
const _ = require('lodash');
const cache = global.yoho.cache;
const sign = global.yoho.sign;
const api = global.yoho.API;
const config = global.yoho.config;
const Auth = {
signin(area, profile, password, shoppingKey) {
let param = {
method: 'app.passport.signin',
area: area,
profile: profile,
password: password
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.post('', param);
},
signinByOtherOpenID(nickname, openId, sourceType, shoppingKey) {
let param = {
nickname: nickname,
openId: openId,
source_type: sourceType,
method: 'app.passport.signinByOpenID'
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
},
signinByWechat(nickname, openId, sourceType, shoppingKey, unionId) {
let param = {
nickname: nickname,
openId: openId,
unionId: unionId,
source_type: sourceType,
method: 'app.passport.signinByWechat'
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
},
signinByOpenID(nickname, openId, sourceType, shoppingKey, unionId) {
let signinFunc = {
other: this.signinByOtherOpenID,
wechat: this.signinByWechat
};
// PC 的微信登录之前使用了 open_id, 所以需要特别的接口处理
let type = sourceType !== 'wechat' ? 'other' : sourceType;
return signinFunc[type](nickname, openId, sourceType, shoppingKey, unionId);
},
profile(uid) {
let param = {
uid: uid,
method: 'app.passport.profile'
};
return api.get('', param);
},
syncUserSession(uid, req, res) {
return Auth.profile(uid).then((userInfo) => {
let token = sign.makeToken(uid);
let user = userInfo.data;
if (!_.isEmpty(user)) {
let uidCookie = `{data.profile_name}::${user.uid}::${user.username}::${token}`;
req.session._TOKEN = token;
req.session._LOGIN_UID = uid;
req.session._USERNAME = user.username;
res.cookie('_UID', uidCookie, {
domain: config.cookieDomain
});
res.cookie('_USERNAME', user.username, {
domain: config.cookieDomain
});
}
req.session._TOKEN = token; // esline-disable-line
req.session._LOGIN_UID = uid; // esline-disable-line
res.cookie('_TOKEN', token, {
domain: config.cookieDomain
}); // esline-disable-line
});
},
rememberAccount(accountInfo, req, res) {
let aWeek = (new Date()).getTime() / 1000 + 504000; // 504000-一周
let rememKey = md5(md5(accountInfo.account + accountInfo.password + accountInfo.area));
res.cookie('isRemember', true, aWeek);
res.cookie('remem', rememKey, aWeek);
if (!cache.get(rememKey)) {
cache.set(rememKey, accountInfo, aWeek);
}
}
};
module.exports = Auth;
... ... @@ -9,79 +9,91 @@
const api = global.yoho.API;
const BindService = {
bindCheck(mobile, openId, sourceType, area) {
let params = {
method: 'app.passport.signCheck',
area: area,
mobile: mobile,
open_id: openId,
source_type: sourceType
};
const bindCheck = (mobile, openId, sourceType, area) => {
let params = {
method: 'app.passport.signCheck',
area: area,
mobile: mobile,
open_id: openId,
source_type: sourceType
};
return api.get('', params);
},
sendBindMsg(area, mobile) {
let params = {
method: 'app.passport.smsbind',
mobile: mobile,
area: area
};
return api.get('', params);
};
const sendBindMsg = (area, mobile) => {
let params = {
method: 'app.passport.smsbind',
mobile: mobile,
area: area
};
return api.get('', params);
},
checkBindCode(area, mobile, code) {
return api.get('', {
method: 'app.register.validRegCode',
mobile: mobile,
area: area,
code: code
});
},
bindMobile(openId, sourceType, mobile, area, password, nickname) {
let params = {
method: 'app.passport.bind',
mobile: mobile,
open_id: openId,
source_type: sourceType,
area: area
};
return api.get('', params);
};
if (password) {
params.password = password;
}
const checkBindCode = (area, mobile, code) => {
return api.get('', {
method: 'app.register.validRegCode',
mobile: mobile,
area: area,
code: code
});
};
if (nickname) {
params.nickname = nickname;
}
const bindMobile = (openId, sourceType, mobile, area, password, nickname) => {
let params = {
method: 'app.passport.bind',
mobile: mobile,
open_id: openId,
source_type: sourceType,
area: area
};
return api.get('', params);
},
relateMobile(openId, sourceType, mobile, area) {
return api.get('', {
method: 'app.passport.relatedMobile',
mobile: mobile,
openId: openId,
source_type: sourceType,
area: area
});
},
changeCheck(mobile, area) {
return api.get('', {
method: 'app.passport.changeCheck',
mobile: mobile,
area: area
});
},
changeMobile(uid, mobile, area, code) {
return api.get('', {
method: 'app.passport.changeMobile',
mobile: mobile,
uid: uid,
code: code,
area: area
});
if (password) {
params.password = password;
}
if (nickname) {
params.nickname = nickname;
}
return api.get('', params);
};
module.exports = BindService;
const relateMobile = (openId, sourceType, mobile, area) => {
return api.get('', {
method: 'app.passport.relatedMobile',
mobile: mobile,
openId: openId,
source_type: sourceType,
area: area
});
};
const changeCheck = (mobile, area) => {
return api.get('', {
method: 'app.passport.changeCheck',
mobile: mobile,
area: area
});
};
const changeMobile = (uid, mobile, area, code) => {
return api.get('', {
method: 'app.passport.changeMobile',
mobile: mobile,
uid: uid,
code: code,
area: area
});
};
module.exports = {
bindCheck,
sendBindMsg,
checkBindCode,
bindMobile,
relateMobile,
changeCheck,
changeMobile
};
... ...
/**
* Created by TaoHuang on 2016/7/25.
*/
'use strict';
const api = global.yoho.API;
const signin = (area, profile, password, shoppingKey) => {
let param = {
method: 'app.passport.signin',
area: area,
profile: profile,
password: password
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.post('', param);
};
const signinByOtherOpenID = (nickname, openId, sourceType, shoppingKey) => {
let param = {
nickname: nickname,
openId: openId,
source_type: sourceType,
method: 'app.passport.signinByOpenID'
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
const signinByWechat = (nickname, openId, sourceType, shoppingKey, unionId) => {
let param = {
nickname: nickname,
openId: openId,
unionId: unionId,
source_type: sourceType,
method: 'app.passport.signinByWechat'
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
module.exports = {
signin,
signinByOtherOpenID,
signinByWechat
};
... ...
... ... @@ -11,11 +11,11 @@ const WeixinStrategy = require('passport-weixin');
const SinaStrategy = require('passport-sina').Strategy;
const LocalStrategy = require('passport-local').Strategy;
const QQStrategy = require('passport-qq').Strategy;
const AlipayStrategy = require('./models/passport-alipay').Strategy;
const AlipayStrategy = require('./passport-alipay').Strategy;
const md5 = require('md5');
const AuthHelper = require('./models/auth-helper');
const loginService = require('./login-service');
const config = global.yoho.config;
const helpers = global.yoho.helpers;
... ... @@ -81,7 +81,7 @@ passport.use(new LocalStrategy({
} else if (ipTimes >= 100) {
done({message: '您尝试的次数过多,账号已被暂时锁定,请稍后再试'}, null);
} else {
return AuthHelper.signin(area, username, password, shoppingKey).then((result) => {
return loginService.signin(area, username, password, shoppingKey).then((result) => {
if (result.code && result.code === 200 && result.data.uid) {
cache.del(errorLoginKey);
... ...
/**
* Created by TaoHuang on 2016/7/25.
*/
'use strict';
const md5 = require('md5');
const _ = require('lodash');
const cache = global.yoho.cache;
const sign = global.yoho.sign;
const config = global.yoho.config;
const api = require('./login-api');
const userService = require('./user-service');
const signinByOpenID = (nickname, openId, sourceType, shoppingKey, unionId) => {
let signinFunc = {
other: api.signinByOtherOpenID,
wechat: api.signinByWechat
};
// PC 的微信登录之前使用了 open_id, 所以需要特别的接口处理
let type = sourceType !== 'wechat' ? 'other' : sourceType;
return signinFunc[type](nickname, openId, sourceType, shoppingKey, unionId);
};
const syncUserSession = (uid, req, res) => {
return userService.profile(uid).then((userInfo) => {
let token = sign.makeToken(uid);
let user = userInfo.data;
if (!_.isEmpty(user)) {
let uidCookie = `{data.profile_name}::${user.uid}::${user.username}::${token}`;
req.session._TOKEN = token;
req.session._LOGIN_UID = uid;
req.session._USERNAME = user.username;
res.cookie('_UID', uidCookie, {
domain: config.cookieDomain
});
res.cookie('_USERNAME', user.username, {
domain: config.cookieDomain
});
}
req.session._TOKEN = token; // esline-disable-line
req.session._LOGIN_UID = uid; // esline-disable-line
res.cookie('_TOKEN', token, {
domain: config.cookieDomain
}); // esline-disable-line
});
};
const rememberAccount = (accountInfo, req, res) => {
let aWeek = (new Date()).getTime() / 1000 + 504000; // 504000-一周
let rememKey = md5(md5(accountInfo.account + accountInfo.password + accountInfo.area));
res.cookie('isRemember', true, {
maxAge: aWeek,
domain: config.cookieDomain
});
res.cookie('remem', rememKey, {
maxAge: aWeek,
domain: config.cookieDomain
});
return cache.set(rememKey, accountInfo);
};
module.exports = {
signin: api.signin,
signinByOpenID,
syncUserSession,
rememberAccount
};
... ...
... ... @@ -46,7 +46,17 @@ const findByEmailAsync = (email) => {
});
};
const profile = (uid) => {
let param = {
uid: uid,
method: 'app.passport.profile'
};
return api.get('', param);
};
module.exports = {
findByMobileAsync,
findByEmailAsync
findByEmailAsync,
profile
};
... ...
... ... @@ -10,10 +10,6 @@ const _ = require('lodash');
const helpers = global.yoho.helpers;
module.exports = (req, res, next) => {
req.getUrl = function() {
return req.protocol + '://' + req.get('host') + req.originalUrl;
};
let refer = '';
if (req.method === 'GET') {
... ...
'use strict';
const _ = require('lodash');
const cookie = global.yoho.cookie;
const cache = global.yoho.cache;
const loginService = require('../../apps/passport/models/login-service');
module.exports = () => {
return (req, res, next) => {
req.getUrl = function() {
return req.protocol + '://' + req.get('host') + req.originalUrl;
};
// 从 SESSION 中获取到当前登录用户的 UID
if (req.session && _.isNumber(req.session._LOGIN_UID)) {
req.user.uid = req.session._LOGIN_UID;
... ... @@ -22,6 +30,26 @@ module.exports = () => {
}
}
next();
// 记住我
if (req.cookies.isRemember && req.cookies.remem && !req.user.uid) {
cache.get(req.cookies.remem).then(result => {
let data = JSON.parse(result);
let account = data.account;
let password = data.password;
let area = data.area;
return loginService.signin(area, account, password);
}).then(result => {
if (result.code !== 200) {
return Promise.reject(new Error(result.message));
}
return loginService.syncUserSession(result.data.uid, req, res);
}).then(()=> {
return res.redirect(req.getUrl());
}).catch(next);
} else {
return next();
}
};
};
... ...