我在服务器端使用HapiJ,并且想基于角色进行路由配置,我想限制用户访问某些端点
var Hapi = require('hapi');
var server = new Hapi.Server();
server.connection({ port: 8000 });
server.route({
method: 'GET',
path: 'api1',
handler: function (request, reply) {
reply('Hello, world!');
}
});
server.route({
method: 'GET',
path: 'api2',
handler: function (request, reply) {
reply('Hello');
}
});
server.route({
method: 'GET',
path: 'api3',
handler: function (request, reply) {
reply('Hello');
}
});
const parseHeader = (request, h) => {
const { role } = JSON.parse(request.headers["roles"]);
};
server.ext("onRequest", parseHeader);
server.start(function () {
console.log('Server running at:', server.info.uri);
});
在这里,我从角色标头获取角色,因此角色可以是“管理员”或“客户”。如果角色是admin,则用户可以访问所有api端点“ api1”,“ api2”和“ api3”,但如果是“客户”,则只能访问“ api3”。
如何在路由上实现这种授权?
答案 0 :(得分:1)
您需要创建“中间件”-预处理程序,它将检查用户的角色, 如果用户的角色是admin,则继续其他操作,拒绝访问
var Boom = require('boom');
const CheckAdmin= function (request, reply) {
const { role } = JSON.parse(request.headers["roles"]);
if(role=='admin'){
return reply.continue();
}else{
return reply(Boom.unauthorized('Access Denied'));
}
}
server.route({
method: 'GET',
path: 'api1',
config: {
pre: [{ method: CheckAdmin }],
handler: function (request, reply) {
reply('Hello, world!');
}
});
server.route({
method: 'GET',
path: 'api2',
config: {
pre: [{ method: CheckAdmin }],
handler: function (request, reply) {
reply('Hello, world!');
}
});
// api3已打开,所有人都可以使用它,因此无需在此处添加预处理程序
server.route({
method: 'GET',
path: 'api3',
handler: function (request, reply) {
reply('Hello');
}
});
答案 1 :(得分:1)
hapi.js具有一个默认机制。称为auth scope。
使用范围字段定义路由的身份验证配置
exports.userList = {
description: 'list users',
auth: {
scope: ['admin]
},
handler: async (request, h) => {
// .. your code here
}
};
这表示,只有管理员范围内的用户才能访问此路由。
然后在您的身份验证代码中将范围字段添加到您的凭据对象。
exports.plugin = {
async register(server, options) {
const implementation = function (server, options) {
return {
authenticate: function (request, h) {
// check user here
const user = findInDbOrSomething();
if (!user) {
// redirect user to login page
return h.redirect('/auth/login').takeover()
}
credentials = {
name: user.name,
email: user.email,
scope: ["admin"] // or user.scope if user has a scope field or get it from somewhere else
}
return h.authenticated({credentials});
}
}
};
server.auth.scheme('basic', implementation);
server.auth.strategy('simple', 'basic');
server.auth.default('simple')
},
name: 'auth',
version: require('../package.json').version
};