express-gateway-plugin-pep
Version:
使用nodejs实现的express-gateway网关权限插件
137 lines (125 loc) • 4.32 kB
JavaScript
var axios = require('axios');
const yaml = require('js-yaml');
const fs = require('fs');//读写文件
const path = require('path');//文件路径操作
const logger = require('../logger');//日子记录
//引入grpc
var grpc_pep = require("./grpc_pep");
//主方法(可导出供其他文件调用)
const start = async (token, domain)=>{
//没有传入access_token
if(typeof(token) === "undefined"){
logger.info('access_token is not set');
return false
}
//读取配置文件
var obj = yaml.safeLoad(fs.readFileSync(path.resolve(__dirname, '..') + "/config/common.config.yml" , 'utf8'));
//读取认证数据authorization
authurl = obj.authurl.host + ":" + obj.authurl.port + obj.authurl.path;
const authorization = await getAuthorization(token, authurl)
//传入的access_token是无效的
if(authorization === false){
logger.info('access_token is invalid or permission is deny');
return false
}
//通过访问者domain读取映射项目,再选择http/grpc, 无论是HTTP还是GRPC,接口返回的数据必须包含 result.allow 属性
for(key in obj.domain_pdp_map){
if(obj.domain_pdp_map[key].domain == domain){
// console.log(obj.domain_pdp_map[key])
if(obj.domain_pdp_map[key].api_type == 'http'){
//进行HTTP请求方式
let url = obj.domain_pdp_map[key]['http'].host + ":" + obj.domain_pdp_map[key]['http'].port + obj.domain_pdp_map[key]['http'].path;
var pdpResult = await getPDP(authorization, token, url);
console.log("api_type: " + obj.domain_pdp_map[key].api_type + " pdp_path: " + obj.domain_pdp_map[key]['http'].path + " token: " + token)
}else{
//grpc请求方式
let grpc = obj.domain_pdp_map[key]['grpc']
let grpc_key = grpc.key
let grpc_namespace = grpc.namespace
let grpc_path = grpc.path
let grpc_address = grpc.host + ":" + grpc.port
var pdpResult = await getPDPGRPC(grpc_key, grpc_namespace, grpc_path, token, authorization, grpc_address);
console.log("api_type: " + obj.domain_pdp_map[key].api_type + " pdp_path: " + grpc_path + " token: " + token)
}
break;
}
}
//PDP返回权限操作结果,当结果 !==true时拦截
if((pdpResult.data.allow) !== true){
logger.info('Your Permission Is Deny');
return false
}
//所有参数正常 且 权限允许则放行
return true; //pdpResult.result.allow
}
//1、调用认证接口(发起GET请求)
const getAuthorization = async (token, authurl)=> {
const data = await axios.get(
authurl,
//header头
{
headers:{
'Content-Type':'application/json',
'domain-id':'paraview.sso360.in',
'Connection':'keep-alive',
'access_token':token,
}
}
);
// console.log(data.headers.authorization)
if(data.headers.authorization == undefined){
return false
}
return data.headers.authorization
};
//2、HTTP调用PDP接口(发起POST请求)
const getPDP = async (authorization, token, pdpurl)=>{
const {data} = await axios.post(
//url
pdpurl,
//param参数
{},
//header头
{
headers:{
'access_token':token,
'Authorization':authorization
},
data:{
"input": {
"user": "bob",
"action": "read",
"resource": "dog1234"
}
}
}
);
// console.log(data)
return data;
};
//2.1、GRPC调用PDP接口(发起GRPC请求)
const getPDPGRPC = async (key, namespace, path, access_token, Authorization, address)=>{
input = '{"input":{"user":"bob", "action":"read", "resource":"dog1234"}}'
const data = await grpc_pep(key, namespace, path, access_token, Authorization, address, input);
let obj = JSON.parse(JSON.stringify(data.data))
// console.log(obj)
result = {
"data":{
"allow": JSON.parse(obj).allow
}
}
return result;
};
//使用全局拦截器获取401,统一返回错误
axios.interceptors.response.use(response => {
return response;
}, error => {
console.log(error.response)
if (error.response.status === 401) {
logger.debug('401 Unauthorized');
process.exit();
}
return error;
});
//3、导出插件模块,供外部调用(调用方法:require('./xxx');)
module.exports = start;