While authentication is a process of verifying the identity of a user, authorization is the process of verifying whether they have the permission to access a resource.
Fortunately, hapi has core support for authorization through scopes that allow us to effectively assign a role to a client when we authenticate them, which may be something such as user or admin.
We can then easily specify what roles are authorized to access a route in our route configuration object through the scope property, by passing a string or array of strings. Let's take a look at what a sample application using scopes would look like:
const Hapi = require('hapi'); const Basic = require('hapi-auth-basic'); const server = new Hapi.Server(); server.connection({ port: 1337 }); server.register([ Basic ], (err) => { // handle err logic const basicConfig = { validateFunc: function (request, username, password, callback) { if (username === 'admin1' && password === 'password') { return callback(null, true, { user: 'admin1', scope: 'admin' }); } if (username === 'user2' && password === 'password') { return callback(null, true, { user: 'user2', scope: 'user' }); } return callback(null, false); } }; server.auth.strategy('simple', 'basic', basicConfig); server.auth.default('simple'); server.route([ { method: 'GET', path: '/admin', config: { auth: { access: { scope: ['admin'] } }, handler: function (request, reply) { return reply(request.auth); } } }, { method: 'GET', path: '/any', config: { handler: function (request, reply) { return reply(request.auth); } } } ]); server.start(() => {}); });
So this looks quite similar to our first basic
authentication scheme example, except that you may have noticed that in our basicConfig
configuration object, we have authentication for two different types of users, an admin user and a normal user, and that we assign a corresponding scope:
if (username === 'admin1' && password === 'password') { return callback(null, true, { user: 'admin1', scope: 'admin' }); }
Also, in our /admin
route, we have added the following:
auth: { access: { scope: ['admin'] } }
This specifies that any client attempting to access the /admin
route must be an authenticated user with a scope of admin
. If not, an HTTP-friendly 403 forbidden error via the boom
module will be returned to the client.
In the scope
array, multiple scopes can be used, which would mean that this route is accessible to a user with any of the following roles, not all of the roles.
The second route, however, doesn't have any scopes configured on the route, and so any authenticated user can access this route, regardless of whether they have a scope.
The scope array actually provides very flexible authorization options, not demonstrated here. For example, if a string in the scope array begins with a +
, that scope is required. If a string in the scope array beings with a !
, it means that scope is forbidden. You can read more about the available scope options in the API documentation at http://hapijs.com/api#route-options.
As mentioned earlier, permission levels are something usually quite common to an application; hapi scopes make for a very easy-to-use and manageable solution for creating an authorization system.
3.138.179.100