Role-Based Access Control
// Role checking middleware\napp.decorate('requireRole', function(...roles) {\n return async (request, reply) => {\n await request.jwtVerify();\n\n if (!roles.includes(request.user.role)) {\n return reply.code(403).send({\n error: 'Insufficient permissions',\n required: roles,\n yourRole: request.user.role,\n });\n }\n };\n});\n\n// Usage\napp.get('/admin/users', {\n preHandler: [app.requireRole('admin')],\n}, async (request) => {\n return db.users.findAll();\n});\n\napp.get('/manager/reports', {\n preHandler: [app.requireRole('admin', 'manager')],\n}, async (request) => {\n return db.reports.findAll();\n});\n\n// Permission-based access\napp.decorate('requirePermission', function(permission) {\n return async (request, reply) => {\n await request.jwtVerify();\n\n const permissions = {\n admin: ['*'],\n manager: ['read:users', 'write:reports', 'read:reports'],\n editor: ['write:posts', 'read:posts'],\n user: ['read:posts'],\n };\n\n const userPermissions = permissions[request.user.role] || [];\n\n if (!userPermissions.includes('*') && !userPermissions.includes(permission)) {\n return reply.code(403).send({ error: 'Missing permission: ' + permission });\n }\n };\n});\n\napp.delete('/posts/:id', {\n preHandler: [app.requirePermission('write:posts')],\n}, async (request) => {\n return db.posts.delete(request.params.id);\n});
Examples
const Fastify = require('fastify');
const app = Fastify({ logger: true });
// RBAC setup
async function build() {
await app.register(require('@fastify/jwt'), {
secret: 'change-me',
});
// Role-based access
app.decorate('canAccess', function(...roles) {
return async (request, reply) => {
try {
await request.jwtVerify();
} catch {
return reply.code(401).send({ error: 'Unauthorized' });
}
if (!roles.includes(request.user.role)) {
reply.code(403);
return { error: 'Forbidden', required: roles, yourRole: request.user.role };
}
};
});
// Routes with different access levels
app.get('/public', async () => ({
message: 'This is public',
}));
app.get('/user/data', {
preHandler: [app.canAccess('user', 'admin', 'manager')],
}, async (request) => ({
message: 'User data',
user: request.user,
}));
app.get('/admin', {
preHandler: [app.canAccess('admin')],
}, async () => ({
message: 'Admin panel',
users: [{ id: 1, name: 'Alice' }],
}));
// Login endpoint
app.post('/login', async (request) => {
const { username, role = 'user' } = request.body;
const token = app.jwt.sign({ username, role }, { expiresIn: '1h' });
return { token, user: { username, role } };
});
await app.listen({ port: 3000 });
}
build();