Authored by 姜枫

微信登录整合

... ... @@ -133,6 +133,9 @@ Session.vim
# auto-generated tag files
tags
### VS Code ###
.vscode/
### YOHO ###
dist
public/css/*
... ...
... ... @@ -39,7 +39,9 @@ app.set('view engine', '.hbs');
app.use(favicon(path.join(__dirname, '/public/favicon.ico')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(session({
proxy: true,
... ...
/**
* passport 验证策略注册
* @author: jiangfeng<jeff.jiang@yoho.cn>
* @date: 2016/5/31
*/
'use strict';
const passport = require('passport');
const WeixinStrategy = require('passport-weixin-plus');
const config = require('../../config/common');
/**
* wechat登录
*/
passport.use(new WeixinStrategy({
clientID: config.wechat.appID,
clientSecret: config.wechat.appSecret,
callbackURL: `${config.siteUrl}/passport/login/wechat/callback`,
requireState: false,
scope: 'snsapi_userinfo'
}, (accessToken, refreshToken, profile, done) => {
done(null, profile);
}));
\ No newline at end of file
... ...
... ... @@ -5,19 +5,65 @@
*/
'use strict';
// const library = '../../../library';
// const _ = require('lodash');
// const channelModel = require('../models/channel');
// const helpers = require(`${library}/helpers`);
// const log = require(`${library}/logger`);
const library = '../../../library';
const passport = require('passport');
const cookie = require(`${library}/cookie`);
const helpers = require(`${library}/helpers`);
const log = require(`${library}/logger`);
const config = require('../../../config/common');
const AuthHelper = require('../models/auth-helper');
/**
* 频道页底部 bannel
* @param {[object]} req
* @param {[object]} res
* @return {[type]}
*/
exports.index = (req, res) => {
res.send('login');
function doPassportCallback(openId, nickname, req, res) {
let shoppingKey = cookie.getShoppingKey(req);
let refer = req.cookies.refer;
if (refer) {
refer = decodeURI(req.cookies.refer);
} else {
refer = `${config.siteUrl}/?go=1`;
}
if (openId && nickname) {
AuthHelper.signinByOpenID(nickname, openId, 'wechat', shoppingKey).then((result) => {
if (result.data['is_bind'] && result.data['is_bind'] === 'N') { //eslint-disable-line
res.redirect(helpers.urlFormat('/passport/bind/index', {
openId: openId,
sourceType: 'wechat'
}));
} else if (result.code === 200 && result.data.uid) {
return AuthHelper.syncUserSession(result.data.uid, res);
}
}).then(() => {
res.redirect(refer);
}).catch((e) => {
log.error('频道页面渲染错误:' + JSON.stringify(e));
res.send('error');
});
}
}
const wechat = {
beforeLogin: (req, res, next) => {
let refer = req.query.refer;
res.cookie('refer', encodeURI(refer));
next();
},
login: (req, res, next) => {
return passport.authenticate('weixin')(req, res, next);
},
callback: (req, res, next) => {
passport.authenticate('weixin', (err, user) => {
if (err) {
return next(err);
}
let nickname = user.nickname;
let openId = user.unionid || user.openid;
doPassportCallback(openId, nickname, req, res);
})(req, res, next);
}
};
exports.wechat = wechat;
\ No newline at end of file
... ...
... ... @@ -3,11 +3,13 @@
* @author: Bi Kai<kai.bi@yoho.cn>
* @date: 2016/05/09
*/
'use strict';
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
var passport = require('passport');
var app = express();
// set view engin
... ... @@ -27,6 +29,11 @@ app.engine('.hbs', hbs({
helpers: require(`${global.library}/helpers`)
}));
require('./auth');
app.use(passport.initialize());
app.use(passport.session());
// router
app.use(require('./router'));
... ...
'use strict';
const library = '../../../library';
const API = require(`${library}/api`).API;
const sign = require(`${library}/sign`);
const api = new API();
class Auth {
static signinByOpenID(nickname, openId, sourceType, shoppingKey) {
let param = {
nickname: nickname,
openId: openId,
source_type: sourceType, // esline-disable-line
method: 'app.passport.signinByOpenID'
};
return api.get('', sign.apiSign(param));
}
static profile(uid) {
let param = {
uid: uid,
method: 'app.passport.profile'
};
return api.get('', sign.apiSign(param));
}
static syncUserSession(uid, req, res) {
return Auth.profile(uid).then((userInfo) => {
let token = sign.makeToken(uid);
let data = userInfo.data;
if (data) {
let uidCookie = `${data.profile_name}::${data.uid}::${data.vip_info.title}::${token}`;
res.cookies._UID = uidCookie;
}
req.session._TOKEN = token; // esline-disable-line
req.session._LOGIN_UID = uid; // esline-disable-line
res.cookies._TOKEN = token; // esline-disable-line
});
}
}
module.exports = Auth;
\ No newline at end of file
... ...
... ... @@ -12,6 +12,7 @@ const login = require(cRoot + '/login');
const router = express.Router(); // eslint-disable-line
router.get('/', login.index); // 登录
router.get('/login/wechat', login.wechat.beforeLogin, login.wechat.login); // 登录
router.get('/login/wechat/callback', login.wechat.callback);
module.exports = router;
\ No newline at end of file
... ...
... ... @@ -4,30 +4,30 @@
* @date: 2016/05/06
*/
var express = require('express'),
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
var app = express();
var app = express();
// set view engin
var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
// set view engin
var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
app.on('mount', function(parent) {
app.on('mount', function(parent) {
delete parent.locals.settings; // 不继承父 App 的设置
Object.assign(app.locals, parent.locals);
});
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
helpers: require(`${global.library}/helpers`)
}));
}));
// router
app.use(require('./router'));
// router
app.use(require('./router'));
module.exports = app;
module.exports = app;
\ No newline at end of file
... ...
... ... @@ -40,13 +40,17 @@ module.exports = {
udp: { // send by udp
level: 'debug', // logger level
host: '192.168.102.162', // influxdb host
port: '4444'// influxdb port
port: '4444' // influxdb port
},
console: {
level: 'debug',
colorize: 'all',
prettyPrint: true
}
},
wechat: {
appID: 'wx3ae21dcbb82ad672',
appSecret: 'e78afb2321e6a19085767e1a0f0d52c1'
}
};
... ...
... ... @@ -3,6 +3,8 @@
* @param {[object]} req
* @return {[string]}
*/
'use strict';
exports.getUid = (req) => {
const cookie = req.cookies._UID;
let _uid = 0;
... ... @@ -21,3 +23,7 @@ exports.getUid = (req) => {
return _uid;
};
exports.getShoppingKey = (req) => {
return req.cookies['_SPK'] ? req.cookies['_SPK'] : ''; // eslint-disable-line
};
\ No newline at end of file
... ...
... ... @@ -11,14 +11,14 @@ const FileTransport = require('winston-daily-rotate-file');
require('influxdb-winston');
const logger = new (winston.Logger)({
transports: [
new (FileTransport)(config.loggers.infoFile),
new (FileTransport)(config.loggers.errorFile),
new (winston.transports.UdpTransport)(config.loggers.udp),
new (winston.transports.Console)(config.loggers.console)
],
exitOnError: false
const logger = new(winston.Logger)({
// transports: [
// new(FileTransport)(config.loggers.infoFile),
// new(FileTransport)(config.loggers.errorFile),
// new(winston.transports.UdpTransport)(config.loggers.udp),
// new(winston.transports.Console)(config.loggers.console)
// ],
// exitOnError: false
});
module.exports = logger;
\ No newline at end of file
... ...
... ... @@ -94,3 +94,7 @@ exports.webSign = (params) => {
return params.key === md5(md5(webPrivateKey) + params.uid);
};
exports.makeToken = (string) => {
return md5(md5(string + '#@!@#'));
};
\ No newline at end of file
... ...
... ... @@ -43,6 +43,8 @@
"moment": "^2.13.0",
"morgan": "^1.7.0",
"oneapm": "^1.2.20",
"passport": "^0.3.2",
"passport-weixin-plus": "0.0.4",
"request-promise": "^3.0.0",
"serve-favicon": "^2.3.0",
"uuid": "^2.0.2",
... ...