HapiJs 基于角色路由访问

Sag*_*che 0 javascript node.js hapijs

我在服务器端使用 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);
});
Run Code Online (Sandbox Code Playgroud)

在这里,我从角色标题中获取角色,因此角色可以是“admin”或“customer”。如果角色是管理员,用户可以访问所有 api 端点“api1”、“api2”和“api3”,但如果是“客户”,则只能访问“api3”。

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

met*_*kos 5

hapi.js 有一个默认机制。它被称为auth scope

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

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

这表示,只有 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
};
Run Code Online (Sandbox Code Playgroud)