bem-auth
Version:
111 lines (106 loc) • 3.29 kB
JavaScript
'use strict';
let jwt = require('jsonwebtoken');
let thunkify = require('thunkify');
let deepcopy = require('deepcopy');
let App = require('bem-app');
let Mongo = require('bem-mongo');
let sha1 = require('bem-sha1');
let Session = require('bem-session');
const ERR = require('bem-errcode');
let sign = function(method, path, data, key) {
let str = '';
if (!key) return null;
try {
str = JSON.stringify(data);
} catch (e) {
return null;
}
let strToSign = `${method.toUpperCase()}/${path}/${str}`;
let signature = sha1(strToSign, key);
return signature;
};
module.exports = function(config) {
let redis = config.redis;
let secret = config.secret;
return function*(next) {
let query = this.request.query || {};
let body = this.request.body || {};
let appId = query.appId || this.headers['x-bem-appid'] || this.cookies.get('appId');
let className = '_User';
if (!appId) {
this.body = deepcopy(ERR.UNAUTHORIZED);
return;
}
let appData = yield App.getAppDataByAppId(appId);
if (!appData) {
this.body = deepcopy(ERR.UNAUTHORIZED);
return;
}
let clientSign = this.headers['x-bem-client-sign'];
let javascriptSign = query.sign || body.sign || this.headers['x-bem-javascript-sign'];
let apiSign = this.headers['x-bem-api-sign'];
let consoleSign = this.headers['x-bem-console-sign'];
let masterKey = this.headers['x-bem-master-key'];
if (!clientSign && !javascriptSign && !apiSign && !consoleSign && !masterKey) {
this.body = deepcopy(ERR.UNAUTHORIZED);
return;
}
if (masterKey && appData.masterKey !== masterKey) {
this.body = deepcopy(ERR.UNAUTHORIZED);
return;
}
if (clientSign && clientSign !== sign(this.method, this.path, body, appData.clientKey)) {
this.body = deepcopy(ERR.UNAUTHORIZED);
return;
}
if (javascriptSign && javascriptSign !== sign(this.method, this.path, body, appData.javascriptKey)) {
this.body = deepcopy(ERR.UNAUTHORIZED);
return;
}
if (apiSign && apiSign !== sign(this.method, this.path, body, appData.apiKey)) {
this.body = deepcopy(ERR.UNAUTHORIZED);
return;
}
if (consoleSign && consoleSign !== sign(this.method, this.path, body, appData.consoleKey)) {
this.body = deepcopy(ERR.UNAUTHORIZED);
return;
}
let token = query.sessionToken || this.headers['x-bem-session'] || this.cookies.get('token');
let userData;
let uid;
if (token) {
let session = yield Session.get({
secret, redis
});
if (consoleSign) {
className = '_Admin';
uid = yield session.checkAdmin(token);
} else {
uid = yield session.check(token);
}
if (uid) {
let mongo = yield Mongo.get({
db: `${appData.name}_${appId}`
});
userData = yield mongo.read({
className: className,
objectId: uid,
isMaster: true,
options: {
keys: {
password: 0
}
}
});
if (userData) {
userData.sessionToken = token;
}
}
}
this.acl=[uid];
this.user = userData;
this.appData = appData;
this.isMaster = !!masterKey;
yield next;
}
};