stalniy / casl

CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access
https://casl.js.org/
MIT License
5.93k stars 269 forks source link

Implementing CASL on Front-End and Backend Use Case #821

Closed zunnurainbadar closed 11 months ago

zunnurainbadar commented 1 year ago

I am trying to implement shared CASL on front end and on the backend side (nestjs). I have multiple use cases:



First, I tried to use use-case based permissions for example I created my ability using this:

Admin:
    can('read', 'Post');
    can('update', 'Post');
    can('delete', 'Post');
    can('read', 'Change Status');
    can('read', 'Add Comment');

User1
    can('read', 'Post', { createdBy: userId });
    can('update', 'Post', { createdBy: userId });
    can('delete', 'Post', { createdBy: userId });
    can('read', 'Change Status', { createdBy: userId });
    can('read', 'Add Comment', { createdBy: userId });

But, I feel that this is not scalable what If I made a typo while checking for permissions? For example, If I check permission using ability.can(read, 'add comments') then it will give me that User is not authorized. Also, If I change the name of my comment module to note then I have to change each and every permission. So, I left this option and then I tried to implement it using Entities. For Example. I created my ability using this (Here Post and Comment is an entity):

Admin:
    can('read', 'Post');
    can('update', 'Post');
    can('delete', 'Post');
    can('read', 'Comment');

User1
    can('read', 'Post', { createdBy: userId });
    can('update', 'Post', { createdBy: userId });
    can('delete', 'Post', { createdBy: userId });
    can('read', 'Comment', { createdBy: userId });

But, I am not sure about this method. In this method, I have multiple Issues

I want to check If I am going in the right direction. Also, Is there any better solution for this?

Any help would be appreciated.

Thanks

abhishekpathak-bitkraft commented 11 months ago

Hey @zunnurainbadar, you got any solution?

stalniy commented 11 months ago

There are 2 ways to go:

  1. Share permissions as is. Works well if backend and front end models are the same/similar
  2. Check permissions on backend and return booleans or an array of permissions for every record in response if models are different or you want to encapsulate knowledge about how permissions are checked on backend