Implementing an Authentication Flow Part 1: Initial Design
This series of article presents a way to perform authentication flow in a React-Native application using Redux, Amazon Web Services (AWS), and multiple authentication providers. While React-Native& Redux are used in this article, the principles applied here should work for multiple different languages across multiple environments.
In a previous post, I presented one method to show a pop up menu. One of my purposes for that menu was to present a “Sign In” button to the user. Pressing this button tells my simple navigator to go to the application’s sign-in screen that presents the user with the option to login using a social network or the Auth-0 authentication service. This series of articles will step through the entire process; from creating the UI using react and Expo.io to logging in using multiple authentication services.
This series of posts has 5 parts:
Upon successful signup, authentication services return something. The exact contents of that something varies between services. However, all the services I’ve used provide some sort of access token enabling user verification. I think of the token as a temporary ID card that my application can show to authentication provider to confirm that the person using my application is actually who they say they are. Think of the application as someone trying to get into a bar, and the authorizer as a bouncer.
Authentication Flow Steps
A flow based on the metaphor results in the following steps:
1. User has an ID and wants me to perform some action
2. User passes me the ID
3. I give the ID to the original issuer
4. Original issuer confirms that the ID is valid
5. I perform the requested user action
In my application this corresponds to:
1. User logs in to authentication service via the application sign in page
2. Application receives information from service, including access token
3. User tells application to perform an action that I determined requires authentication. For example, save an image to the server.
4. Application passes that request to an authorizer that safely resides on my server away from any malicious actors who only have access the application. Additionally, the access token is passed with the same request.
5. The authorizer receives the request and access token.
6. Authorizer passes the access token to the authorization service which checks the token’s validity and responds.
7. Based on that response, the authorizer either tells my application
“No, I’m not going to do this because your token was invalid so I’m not sure you’re really who you say you are”
“Yes, your token was valid, and since the service vouched for you, I’ll do what you want me to do”
Of course, the application isn’t going to speak plain language, but hopefully, this conveys the idea. The animation below also conveys the authentication flow.
So far, I’ve mentioned the authorizer a couple of times so I should probably explain it. An authorizer is a function with the following characteristics:
a. Receives takes the authentication information desired by authentication provider as an input. This is typically the access token.
b. Receives the desired action to performed as an input
a. Passes the access token to the authentication provider.
b. Receives the validity of the token from the authentication provider
i. The authentication service may respond with information that indicates that the token is:
4. Something else depending on the provider
c. Based on the authentication provider’s response, the authorizer performs the desired action or sends a response to the application indicating it won’t perform the action, and why.
In addition to React-Native, Redux, and AWS, my application uses the Expo.io framework. Expo exposes APIs for Google and Facebook authentication. Not only are those flows covered in the documentation, Expo presents examples of how to use each at https://snack.expo.io. The Snack web application lets a user drag and drop components into a React-Native application. I created a “snack” with Facebook login functionality here https://snack.expo.io/BkNljxMxb. This application presents the user with the usual login with Facebook flow which is covered here https://developers.facebook.com/docs/facebook-login/web. Successful authentication with the Facebook login service returns authentication and user ID information that can be used later.
Amazon Web Services
Implementing this plan requires not only an application that the user interacts with, but server functionality to securely authenticate with the authentication providers. While one could verify authentication from the client’s device, there’s nothing stopping a malicious client from “vouching” for themselves by posting fake information or playing with messages passed to your API.
Of course dealing with a server comes with its own problems. To avoid some of the issues with spinning up and maintaining a server, I’ll be using Amazon Web Services’ API Gateway and Lambda functions as the backend. In fact the authorizer mentioned above will be a Lambda function.
The flow for a valid authentication token is shown below. It shows where Lambda and API Gateway fit in.
On the other hand, an invalid access token will result in the following flow.
In the next post, I’ll discuss how I actually implemented everything presented here.
Reginald Johnson has maintained his passion for coding throughout his 20+ year career as an Officer in the United States Navy. He enjoys applying his training and experience in programming, Systems Engineering, and Operational Planning towards programming. Follow him Twitter @reginald3.