HapiJs根据角色路由访问

时间:2019-02-06 08:09:30

标签: javascript node.js hapijs

我在服务器端使用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”。

如何在路由上实现这种授权?

2 个答案:

答案 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
};
相关问题