I'm looking for a way to create a basic authentication for my react-native app. I couldn't find any good example for react-native app.
- To login, the app sends the email/password + clientSecret to my server
- If OK, the server returns accessToken + refreshToken
- The user is logged in, all other requests include the bearer with the accessToken.
- If the accessToken expires, the app requests a new one with the refreshToken automatically.
- The user stays logged in all the time, the states should be saved in the phone.
What would be the best approach for this?
Thanks.
I haven't seen too much by way of examples in this area, and think it's definitely something that needs more coverage. I've not yet implemented auth myself, else I'd point you to some code examples. But I can point you to a couple links I've collected that may help you in the right direction...
Regardless how you perform your auth, you'll need to securely store your access, refresh, and secret tokens. On iOS I believe you'd do that using keychain and for Android it looks like KeyStore is the way. You may find oblador/react-native-keychain helpful, though it doesn't yet support android it looks like it may support android soon.
When an app communicates with a HTTP API which enforces some form of authentication, the app typically follows these steps:
Logging In
Based on the work flow defined above our app starts by displaying a login form, step 2 kicks in when the user taps the login button which dispatches the
login
action creator below:There's a lot of code in the function above, but take comfort in the fact that the majority of the code is sanitising the response and can be abstracted away.
The first thing we do is dispatch an action
LOGIN_REQUEST
which updates our store and lets us know that the userisLoggingIn
.We use this to display an activity indicator (spinning wheel, "Loading...", etc.), and to disable the log in button in our log in view.
Next we base64 encode the user's username and password for http basic auth, and pass it to the request's headers.
If everything went well, we'll dispatch a
LOGIN_SUCCESS
action, which results in us having an authenticationhash
in our store, which we'll use in subsequent requests.On the flip side, if something went wrong then we also want to let the user know:
The
loginSuccess
,loginFailure
, andloginRequest
action creators are fairly generic and don't really warrant code samples. See: https://github.com/peterp/redux-http-basic-auth-example/blob/master/actions/user.js)Reducer
Our reducer is also typical:
Subsequent API requests
Now that we have an authentication hash in our store we can pass it into subsequent request's headers.
In our example below we're fetching a list of friends for our authenticated user:
You may find that most API requests typically dispatch the same 3 actions as above:
API_REQUEST
,API_SUCCESS
, andAPI_FAILURE
, and as such the majority of the request/ response code can be pushed into Redux middleware.We fetch the hash authentication token from the store and setup the request.
If the API response with a 401 status code then we've got to remove our hash from the store, and present the user with a log in view again.
I've answered the question generically and only dealing with http-basic-auth.
I think that the concept may remain the same, you'll push the
accessToken
andrefreshToken
in the store, and extract it in subsequent requests.If the request fails then you'll have to dispatch another action which updates the accessToken, and then recalls the original request.
I'm actually working on a video tutorial series that answers at least some of the questions your asking. The video along with a transcript and sample code can be found here: http://codecookbook.co/post/how-to-build-a-react-native-login-form-with-redux-pt1/