This assumes you have a basic knowledge of react, react-router, redux and redux-middlewares. Also, you have already implemented authentication in the react-redux app.
Note: I have used redux but the same can be done without relying on redux. So, while some knowledge of redux may help you understand what I have tried to convey, redux isn't a necessity.
While working in a project, the requirement arose to give the functionality of Role based access control (RBAC) in a client-side-rendered react-app.
Basically, the application was going to have multiple tiers of users with flexible permissions and depending on the permission granted to any particular user, a component or a part of the application may/may not become accessible to that user.
Implementing RBAC at the client-side can be divided into:
- Conditional rendering of the components
- Updating the conditions when permissions change
Conditional Rendering of the components:
There are many approaches that can be used for this. One of my initial approach was to wrap the component (say CheckedComponent) with a component (say CheckPermissions) which would conditionally render them based on the permissions given to the current user. This looks something like this:
The user-permissions were stored in the redux-store route-wise.
The above approach does the job but fails if the <CheckedComponent />
also requires permission checking, basically making the whole process nested. Also, I didn’t know before-hand the depth of nesting.
I could also have used HoCs, but they too suffered from the same issue, in my case.
So, I decided to go with the hooks approach, which looks something like this:
- the
useAuthorization
hook returns the list of permissions the user has for the given route. This may seem repetitive as this could directly have been taken from theredux-store
, but this hook provided a level of abstraction. Also, if the permission-retrieval logic for the user is changed, only this needed to be changed and everything would still work. - each component is conditionally rendered based on the user permissions.
Updating the conditions when permissions change:
In my case, whenever a user logged in, the server responded with a set of permissions associated with that user. I wrote a middleware which on login-success read the permissions and updated the redux-store
. I am also using redux-persist to save authorization and authentication information about the user in the local storage.
Now, when the permissions are changed for any user, the user’s authorization-token is expired. This is very important or the user-permissions won’t be updated in the redux-store and no change will be visible. The changes with the new permissions are reflected when the user logins again.
This approach of RBAC may not be what’s ideal, but this works for me. A few important steps I have skipped over, as they are subjective to an application, viz.,
- Agreeing on the structure of the permissions. In my case, I arranged the permissions
route-wise
, but you can use any other structure. - The redux-middleware part. This basically takes the server-response and transforms that into the structure mentioned in the first point.
This post is also availabe as a medium post and can be found here :
Top comments (2)
Amazing!
Do you have a repo for this project?
Thank you!
Besides the code-snippets provided in the article, I don't really have a sample PoC project for this. Sorry.