【问题标题】:HapiJs routes access base on roleHapiJs 基于角色路由访问
【发布时间】:2019-02-08 15:46:28
【问题描述】:

我在服务器端使用 HapiJs,想根据角色进行路由配置,我想限制用户访问某些端点

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' 可以访问。

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

【问题讨论】:

    标签: javascript node.js hapijs


    【解决方案1】:

    hapi.js 有一个默认机制。它叫做auth scope。

    使用范围字段定义路由的身份验证配置

    exports.userList = {
        description: 'list users',
        auth: {
            scope: ['admin]
        },    
        handler: async (request, h) => {
            // .. your code here
        }
    };
    

    这表示,只有 admin 范围内的用户可以访问此路由。

    然后在您的身份验证代码中将范围字段添加到您的凭据对象。

    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
    };
    

    【讨论】:

      【解决方案2】:

      您需要创建“中间件” - 将检查用户角色的预处理程序, 如果用户的角色是 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是开放的,都可以使用,这里不需要添加pre handler

      server.route({
        method: 'GET',
        path: 'api3',
        handler: function (request, reply) {
          reply('Hello');
        }
      });
      

      【讨论】:

        猜你喜欢
        • 2021-07-02
        • 1970-01-01
        • 1970-01-01
        • 2016-06-12
        • 2012-01-01
        • 1970-01-01
        • 2015-07-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多