Authored by 李奇

change:修改

/**
*aes加解密
* @author: qi.li@yoho.cn
* @date: 2017/10/10
*/
'use strict';
const crypto = global.yoho.crypto;
/**
* uid加密
**/
const encryptUid = (uid) => {
return crypto.encryption('yoho9646abcdefgh', uid + '');
};
/**
* uid解密
**/
const decryptUid = (uid) => {
return crypto.decrypt('yoho9646abcdefgh', uid + '');
};
module.exports = {
encryptUid,
decryptUid
};
... ...
... ... @@ -3,11 +3,9 @@
* @author: leo <qi.li@yoho.cn>
* @date: 27/09/2017
*/
const GET_COUPON_SUCCESS = '获取优惠券列表成功';
const RECEIVE_COUPON_SUCCESS = '成功领取优惠券';
const NEED_YH_AUTH = '请先授权登录有货';
const HELP_SUCCESS = '助力成功';
const _ = require('lodash');
const aes = require('./aes');
const expModel = require('../models/coupon-expansion');
const couponExp = {
... ... @@ -16,10 +14,41 @@ const couponExp = {
* @param req
* @param res
*/
couponList(req, res) {
res.json({
code: 200,
message: GET_COUPON_SUCCESS
couponList(req, res, next) {
const activityId = +req.query.activity_id;
req.ctx(expModel).couponList(activityId)
.then(result => {
// 初始券数据
req.session._COUPONS = result.data.activityCouponInfoBoList;
res.json(result);
}).catch(next);
},
/**
* 助力进度
* @param req
* @param res
*/
progress(req, res) {
const uid = +req.session.yh_auth_uid;
const shareId = aes.encryptUid(uid); // 分享标识
req.ctx(expModel).progress(uid).then(result => {
result.data.shareId = shareId;
res.json(result);
});
},
/**
* 生成分享标识
* @param req
* @param res
*/
getShareId(req, res) {
req.ctx(expModel).progress(+req.session.yh_auth_uid)
.then(result => {
res.json(result);
});
},
... ... @@ -28,23 +57,47 @@ const couponExp = {
* @param req
* @param res
*/
receiveCoupon(req, res) {
let yhAuth = req.session.yh_auth_logged;
let urlBefore = req.body.url_before_auth;
receiveCoupon(req, res, next) {
let uid = +req.body.uid;
let isApp = req.body.isApp;
if (yhAuth) {
res.json({
code: 200,
message: RECEIVE_COUPON_SUCCESS
// app登录后领券
if (isApp && uid) {
const coupons = req.session._COUPONS;
let promises = _.map(_.filter(coupons, cp => !cp.user_send), item => {
return req.ctx(expModel).getCoupon(uid, item.couponId);
});
} else {
req.session.url_before_auth = urlBefore;
if (promises.length) {
Promise.all(promises).then(() => {
// const success = _.every(result, { code: 200 });
// if (!success) {
// // 领取失败、返回首页
// return res.status(301).redirect('//feature.yoho.cn/coupon-expansion');
// }
// 设置优惠券状态
_.each(coupons, item => {
item.user_send = true;
});
req.session._COUPONS = coupons;
// 进度页
res.status(301).redirect('//feature.yoho.cn/coupon-expansion/progress');
}).catch(next);
} else {
res.json({
code: 401,
message: NEED_YH_AUTH
code: 301,
data: {
url: '//feature.yoho.cn/coupon-expansion/progress'
},
message: '重定向'
});
}
}
// TODO H5
},
/**
... ... @@ -52,16 +105,36 @@ const couponExp = {
* @param req
* @param res
*/
yhLoginSuccess(req, res) {
let uid = req.query.yh_uid;
let url = req.session.url_before_auth;
yhLoginSuccess(req, res, next) {
const uid = req.query.yh_uid;
const coupons = req.session._COUPONS;
req.session.yh_auth_uid = uid;
req.session.yh_auth_logged = true;
delete req.session.url_before_auth;
let promises = _.map(_.filter(coupons, cp => !cp.user_send), item => {
return req.ctx(expModel).getCoupon(uid, item.couponId);
});
Promise.all(promises).then(result => {
const success = _.every(result, { code: 200 });
// TODO
if (!success) {
// 领取失败、返回首页
return res.status(301).redirect('//feature.yoho.cn/coupon-expansion');
}
// 设置优惠券状态
_.each(coupons, item => {
item.user_send = true;
});
req.session._COUPONS = coupons;
// 进度页
res.status(301).redirect('//feature.yoho.cn/coupon-expansion/progress');
}).catch(next);
res.status(301).redirect(url);
},
/**
... ... @@ -69,11 +142,17 @@ const couponExp = {
* @param req
* @param res
*/
expandOne(req, res) {
res.json({
code: 200,
message: HELP_SUCCESS
});
friendHelp(req, res, next) {
const uid = parseInt(aes.decryptUid(req.body.shareId), 10);
const params = Object.assign({}, req.session._THIRD_LOGIN_INFO);
params.uid = uid;
req.ctx(expModel).friendHelp(params)
.then(result => {
// req.session._THIRD_LOGIN_INFO = {};
res.json(result);
}).catch(next);
}
};
... ...
... ... @@ -3,26 +3,58 @@
* @author: leo <qi.li@yoho.cn>
* @date: 27/09/2017
*/
const mysqlCli = global.yoho.utils.mysqlCli;
const TABLE_ACT_LOGIN_USER_LOG = 'act_login_user_log';
class UserModel extends global.yoho.BaseModel {
class expModel extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
loginLog({uid, ip, loginTime, platform, referer}) {
return mysqlCli.insert(
`insert into ${TABLE_ACT_LOGIN_USER_LOG} (user_id, login_time, platform, ip, referer) values (:uid, :loginTime, :platform, :ip, :referer);`, // eslint-disable-line
{
couponList(id) {
return this.get({
data: {
method: 'app.activity.getActivityUserDesc',
activity_id: id
},
api: global.yoho.API,
param: {code: 200}
});
}
getCoupon(uid, couponId) {
return this.get({
data: {
method: 'app.promotion.getCoupon',
uid,
couponId
},
api: global.yoho.API
});
}
friendHelp({ uid, source, openId, nickname, headIco }) {
return this.get({
data: {
method: 'app.activity.friendhelp',
uid,
loginTime,
platform,
ip,
referer
source,
open_id: openId,
nick_name: nickname,
head_ico: headIco
},
api: global.yoho.API,
param: {code: 200}
});
}
);
progress(uid) {
return this.get({
data: {
uid,
method: 'app.activity.friendhelplog'
},
api: global.yoho.API,
param: {code: 200}
});
}
}
module.exports = UserModel;
module.exports = expModel;
... ...
... ... @@ -9,7 +9,8 @@ const couponExp = require('./controllers/coupon-expansion');
router.get('/couponExp/couponList', couponExp.couponList);
router.post('/couponExp/receiveCoupon', couponExp.receiveCoupon);
router.get('/couponExp/progress', couponExp.progress);
router.get('/couponExp/yhLoginSuccess', couponExp.yhLoginSuccess);
router.post('/couponExp/expandOne', couponExp.expandOne);
router.post('/couponExp/friendHelp', couponExp.friendHelp);
module.exports = router;
... ...
... ... @@ -13,12 +13,14 @@ const QQStrategy = require('passport-qq').Strategy;
const config = global.yoho.config;
let siteUrl = config.siteUrl.indexOf('//') === 0 ? 'http:' + config.siteUrl : config.siteUrl;
let weChatUrl = `${siteUrl}/passport/login/wechat/callback`;
let sinaUrl = `${siteUrl}/passport/login/sina/callback`;
// wechat 登录
passport.use('weixin', new WeixinStrategy({
clientID: 'wx75e5a7c0c88e45c2',
clientSecret: 'ce21ae4a3f93852279175a167e54509b',
callbackURL: `${siteUrl}/passport/login/wechat/callback`,
callbackURL: `//m.yohobuy.com/passport/login/wechat/redirect?redirectUrl=${weChatUrl}`,
requireState: true,
authorizationURL: 'https://open.weixin.qq.com/connect/oauth2/authorize',
scope: 'snsapi_userinfo'
... ... @@ -30,7 +32,7 @@ passport.use('weixin', new WeixinStrategy({
passport.use('sina', new SinaStrategy({
clientID: '3739328910',
clientSecret: '9d44cded26d048e23089e5e975c93df1',
callbackURL: `${siteUrl}/passport/login/sina/callback`,
callbackURL: `//m.yohobuy.com/passport/login/sina/redirect?redirectUrl=${sinaUrl}`,
requireState: false
}, (accessToken, refreshToken, profile, done) => {
done(null, profile);
... ...
... ... @@ -9,9 +9,19 @@ const utils = global.yoho.utils;
const AuthHelper = require('../models/auth-helper');
const loginPage = `${config.siteUrl}/signin.html`;
function doPassportCallback(openId, nickname, sourceType, req, res) { // eslint-disable-line
if (openId && nickname) {
// TODO 授权成功、实现助力
function doPassportCallback(openId, nickname, source, req, res) { // eslint-disable-line
if (openId && nickname && source) {
req.session._THIRD_LOGIN_INFO = {
openId,
nickname,
source
};
// 第三方登录
req.session._THIRD_LOGIN = true;
req.session._THIRD_LOGIN_SOURCE = source;
res.status(301).redirect(`${req.session.cbUrl}`);
} else {
return Promise.reject('missing third party login openId or nickname');
}
... ... @@ -133,73 +143,46 @@ const common = {
const wechat = {
login: (req, res, next) => {
// 设置为原链接标识originalUrl
req.session.originalUrl = 'true';
req.session.authState = uuid.v4();
delete req.session._WX_PASS_LOGIN;
req.session.cbUrl = req.query.cbUrl;
return passport.authenticate('weixin', {
state: req.session.authState
})(req, res, next);
},
callback: (req, res, next) => {
if (req.session && req.session.authState && req.session.authState === req.query.state) {
passport.authenticate('weixin', (err, user) => {
if (err || !user) {
log.error(`wechat authenticate error : ${JSON.stringify(err)}`);
return res.redirect(loginPage);
}
let nickname = user._json.nickname || user.displayName;
let openId = user._json.unionid || user.id;
callback: (req, res) => {
const openId = req.query.openId;
const nickname = req.query.nickname;
res.session._WX_OPENID = _.get(user, '_json.openid');
res.session._WX_UNIONID = _.get(user, '_json.unionid');
res.session._LOGIN_TYPE = 4;
doPassportCallback(openId, nickname, 'wechat', req, res).catch(next);
})(req, res, next);
} else {
log.error('Auth State Mismatch:' + req.originalUrl);
return res.redirect(loginPage);
}
doPassportCallback(openId, nickname, 'qq', req, res);
}
};
const sina = {
login: (req, res, next) => {
// 设置为原链接标识originalUrl
req.session.originalUrl = 'true';
req.session.authState = uuid.v4();
req.session.cbUrl = req.query.cbUrl;
return passport.authenticate('sina', {
state: req.session.authState
})(req, res, next);
},
callback: (req, res, next) => {
if (req.session && req.session.authState && req.session.authState === req.query.state) {
passport.authenticate('sina', (err, user) => {
if (err || !user) {
log.error(`sina authenticate error : ${JSON.stringify(err)}`);
return res.redirect(loginPage);
}
let nickname = user.screen_name;
let openId = user.id;
callback: (req, res) => {
const openId = req.query.openId;
const nickname = req.query.nickname;
res.cookie('_LOGIN_TYPE', 2, {
domain: 'm.yohobuy.com'
});
doPassportCallback(openId, nickname, 'sina', req, res).catch(next);
})(req, res, next);
} else {
log.error('Auth State Mismatch:' + req.originalUrl);
return res.redirect(loginPage);
}
doPassportCallback(openId, nickname, 'sina', req, res);
}
};
const qq = {
login: (req, res, next) => {
// 设置为原链接标识originalUrl
req.session.originalUrl = 'true';
req.session.authState = uuid.v4();
req.session.cbUrl = req.query.cbUrl;
return passport.authenticate('qq', {
state: req.session.authState
})(req, res, next);
... ... @@ -210,15 +193,16 @@ const qq = {
if (err) {
log.error(`qq authenticate error : ${JSON.stringify(err)}`);
// TODO 授权失败
// return res.redirect(loginPage);
return res.json({
code: 500,
message: 'authenticate error'
});
}
let nickname = user.nickname;
let openId = user.id;
req.session._LOGIN_TYPE = 1; // 1: QQ授权登录
doPassportCallback(openId, nickname, 'qq', req, res).catch(next);
doPassportCallback(openId, nickname, 'qq', req, res);
})(req, res, next);
} else {
log.error('Auth State Mismatch:' + req.originalUrl);
... ... @@ -227,31 +211,7 @@ const qq = {
}
};
const alipay = {
login: (req, res, next) => {
// 设置为原链接标识originalUrl
req.session.originalUrl = 'true';
return passport.authenticate('alipay')(req, res, next);
},
callback: (req, res, next) => {
passport.authenticate('alipay', (err, user) => {
if (err || !user) {
log.error(`alipay authenticate error : ${JSON.stringify(err)}`);
return res.redirect(loginPage);
}
let nickname = user.realName;
let openId = user.userId;
res.cookie('_LOGIN_TYPE', 3, {
domain: 'm.yohobuy.com'
});
doPassportCallback(openId, nickname, 'alipay', req, res).catch(next);
})(req, res, next);
}
};
exports.common = common;
exports.wechat = wechat;
exports.sina = sina;
exports.qq = qq;
exports.alipay = alipay;
... ...
... ... @@ -21,7 +21,7 @@ router.get('/login/wechat', login.wechat.login);
router.get('/login/wechat/callback', login.wechat.callback);
// sina
router.get('/login/sina', login.common.beforeLogin, login.sina.login);
router.get('/login/sina', login.sina.login);
router.get('/login/sina/callback', login.sina.callback);
// qq
... ...
... ... @@ -3,6 +3,7 @@ const _ = require('lodash');
const {yoho} = global.yoho.utils;
const {yohoSecret} = global.yoho.config;
const UserModel = require('../models/user');
const isProd = process.env.NODE_ENV === 'production';
const user = {
getLoginUrl(req, res) {
... ... @@ -27,7 +28,7 @@ const user = {
return res.json({
code: 200,
loginUrl: `https://m.yohobuy.com/signin.html?${queryStr}`
loginUrl: `http${isProd ? 's' : ''}://m.yohobuy.com/signin.html?${queryStr}`
});
},
loginLog(req, res, next) {
... ...