Composing authorization into React Apps

Sarat Chandra Balla
3 min readFeb 27, 2018

--

Okay, here is the problem. I have a react app with tens of different pages with a quintillion components with ever changing role based authorization rules. I am completely tired of changing the authorization logic in every update.

All I needed was a generic auth solution which has these features

  • Should work with my existing components
  • Should work not only at a route level but also at component level
  • Should have means to display components only to logged out users

So, I set out on a great journey seeking answers (searching for npm packages), with no luck. Then I stumbled upon a great medium post, which inspired me a lot. Realising that there isn’t a ready made solution, I started working on this npm package which solves the Authorization problem once and for all.

Behold react-identity

It provides a simple provider which leverages the composable nature of react components along with the react context.

The AuthProvider:

AuthProvider accepts 4 props: user, updater, loggedOutRole, roleAccessor.

Configuring AuthProvider

user: User object can be passed to the AuthProvider which makes it available across the app via context.

updater: Especially useful if using data store like redux. It is called only once. It has only one argument setUser which is a function which sets the state inside the provider.

roleAccessor: Accessor function to extract role from the user object. Defaults to (user) => (user.role)

loggedOutRole: Role which needs to be used to identify if the user is logged out. Useful if you need to show components only to logged out users.

All the 4 props are optional. As we may not have user object when the initial state of the application. We may not use the updater if we are not using data store like redux. We may not use loggedOutRole if we don’t need to show components only to logged out users. And roleAccessor if the role is present at user.role

Once we have the AuthProvider set up, we can look at how to retrieve and update the user.

The withUser, withUpdater HOC’s:

withUser, withUpdater HOC’s

The withUser HOC passes the user object to the component on which it is applied. The withUpdater passes a function to which a user object can be passed, which then gets store in the AuthProvider state and is reflected across the application instantly.

The withAuthorization HOC:

In order to show the component only to users with specific roles, you can use the `withAuthorization` with the accepted roles.

withAuthorization HOC

It accepts two arguments, an array of authorized roles and a config object.

If user role matches with any of the roles, the component will be rendered. If we need to render a different component if the user is unauthorized, we can pass a react element using the config object. If it is not specified and the user is unauthorized, nothing will be rendered.

Thats all this package offers, but thats not the end of the story. Remember the problem that I explained in the beginning of this post? The ever changing user roles. I’ve solved it using this crazy solution.

Dynamically generated HOC’s based on hierarchy

Here i’m dynamically generating HOC’s based on the power given in the USER_ROLES object.

Authorization using the dynamically generated HOC’s:

Using dynamically generated HOC’s

Using Authorization with react-router:

Hope this helps you. Please let me know your comments and suggestions. If you feel like something is missing, you can always raise a PR on Github.

--

--