Authentication for a React/React Native project is a task that you will see in your project backlog whatever you are working on a simple or complex application. And having a complete guide or a generic approach to do it will help maintain code and save time.
In today’s article, I will share my solution, that I fell it’s the right way to handle authentication in a React Native Project. If you have some ideas to improve the implementation feel free to leave a comment.
For this guide, We aim to build a generic solution that handles most of the authentication use cases and easy to copy-paste in your next project.
From my experience dealing with the same task, i would say that the solution must be:
- Generic and reusable.
- Should provide a
useAuth
hook to access the Auth state and Actions. - Should be secure, using the right solution to secure tokens and user data.
- Should provide A way to invoke the Athentication Action outside React component tree. ( call signOut inside an apollo graphql generic error as an example).
- Performance
Approach :
We will need an Auth provider to save our auth state status
and create some action as signIn
signUp
signOut
to update the Auth state. Then we need to create a custom hook that we can use to access state and action anywhere in our code. We will use the most secure options to persist state and store user tokens. Finally, our solution will provide a way to get access to auth actions outside components three using some react refs tricks.
will use Typescript for code example as we start using it for new projects 😎
Create The Authentication Context.
Maybe you are familiar with a state Management library solution to handle such cases, but I think using React Conext Api is More than enough to handle authentication and provide a clean and complete solution without installing a third-party library.
if you are using a state library to manage your project state, you can use it for Authentication too, and maybe get some inspiration from my solution.
First, we are going to create a simple Authentication context and implement the Provider components.
As we have 3 state loading
, singOut
, signIn
for Auth status
, I think using an enumeration state is the best choice to prevent bugs and to simplify the implementation. Also, we will need the userToken
state to save the token.
Using a reducer hook approach to update the state will help make our code clean and easy to follow.
We create our auth actions using useMemo
hook to memoize them, This optimization helps to avoid generating new instances on every render.
To make using our state more enjoyable and easy, we will create a simple Hook that returns our Auth state and actions and throw an error whenever the user trying to get Auth state without wrapping React tree with AuthProvider
Store Tokens: The secure way
It’s a little bit confusing to see almost all people using local storage to store token as it’s not the most secure one, maybe i can understand if people using it to make their post easy to follow, but i think it’s not recommended to use it in production and instead you need to use secure storage solution such as Keychain. Unfortunately React Native does not come bundled with any way of storing sensitive data. However, there are pre-existing solutions for Android and iOS platforms.
In this part we are going to implement the getToken
, setToken
and removeToken
using react-native-sensitive-data package.
On Android, RNSInfo will automatically encrypt the token using keystore and save it into shared preferences and for IOS, RNSInfo will automatically save your data into user’s keychain which is handled by OS.
To get started, First Make sure to install react-native-sensitive-data
dependency :
Then we can eaisly implement our helpers functions like the fllowing:
If you are using expo you can switch to expo-secure-data
package instead of react-native-sensitive-info
Access Auth Actions outside component three.
One of the limitations using the provider in react is that you can’t use context action outside the React component tree.
For Authentication workflow, i found my self want to signOut user on some error issue caught on Apollo client or maybe or inside a non-component thing.
Recently I found a quick and easy solution that lets you get access Auth context actions outside the component tree using a react reference.
The idea was to create a global React reference and use useImperativeHandle
hook to expose auth actions to our global Ref like the following :
Demo
To use the solution we need to wrap our Root component with AuthProvider and start using useAuth
to access and update state.
Wrap Up
- You can find complete source code 👉 react-native-auth
- Expo Demo : Demo
I hope you found that interesting, informative, and entertaining. I would be more than happy to hear your remarks and thoughts about this solution in The comments.
If you think other people should read this post. Tweet,share and Follow me on twitter for the next articles.
Originally published on https://obytes.com/