Getting people to sign up in one click with Twitter is an effective and easy way to divert and convert people to utilize the app.
To grow your app’s customer base, we need to make onboarding as ridiculously easy as possible. We need to ensure that there is almost zero resistance to people signing up for your app. Getting people to sign up in one click using their already existing accounts is an effective and easy way to divert and convert people to utilize the app.
The usual networks where we can get a significant amount of traffic to convert include the usual suspects such as Facebook, Google, and Twitter. Twitter boasts of 330 million monthly active users in 2021, according to a statistic from Oberlo. Such a number is nothing to sneeze at. It is useful to learn how we can make the sign-up process dead simple for Twitter users.
In this tutorial, we will show you:
Let’s get started!
Registration is always the first step in creating an integration into your app. App creation and registration with Twitter is reasonably straightforward.
Integrating Twitter Login into your app is a highly involved exercise that requires a lot more energy than I think it should. The effort (and the resulting headache) needed to integrate Facebook Login, or Google Login pales into comparison against integrating Twitter.
Let’s leverage on a working code instead of starting from scratch. Download the demo source code from https://github.com/QuodAI/tutorial-react-twitter-api-login.
git clone firstname.lastname@example.org:QuodAI/tutorial-react-twitter-api-login.git
We will see that we have two main folders: the react folder and the express folder. Let us focus our attention on the react folder for now.
The react folder is a reasonably standard React app created via create-react-app. Go to react/src/App.js to see where most of the magic happens.
Before we proceed any further, we must understand Twitter’s 3-legged OAuth. The whole demo app boils down to securely implementing, in React and Express, the 3-legged OAuth that the OAuth 1.0a protocol specified. The protocol allows this app to perform actions on behalf of a user who explicitly permitted it. In this case, the user authorizes the app to access the user’s display name, profile image, URL, and status (aka “last tweet”).
Line 21-27: The app initiates the “dance” by requesting a request token from the endpoint. It does not need any input parameters and will promptly give you both a request token (oauth_token) and a request token secret (not visible - resides in the backend). The request token is a prerequisite for all of the succeeding steps. We may use the request token as the requestor’s identifier.
Observe: Instead of directly accessing the Twitter API, we instead send the request back to the app. We shall see how and why we need to “proxy” our calls to an Express backend instead of directly calling the API.
Line 28-29: Once we have a request token, the app may redirect the user to oauth/authenticate. We have two scenarios:
In both scenarios, the API will redirect back to our app. The callback URL is the location where the Twitter API will redirect after the user successfully logs in. We will set the callback URL later when we return to configuring our Twitter app in the Development Portal.
The redirect will also give two query parameters: it will give back the request token (oauth_token) and a value called oauth_verifier.
The existence of the oauth_verifier value signifies that we correctly authenticated the user.
Line 57-66: We now pass oauth_token, oauth_verifier, and a third value that only resides in the backend server called oauth_token_secret to the oauth/access_token endpoint in exchange for access tokens oauth_access_token and oauth_access_token_secret.
Note that the access tokens are never exposed to React. They stay hidden in the Express backend to make our app secure.
Line 69-83: Once we obtained the access tokens, we can now access all the Twitter API available to us. Our /twitter/users/profile_banner invokes the twitter API https://api.twitter.com/1.1/account/verify_credentials.json to retrieve and display the user’s name, profile image, blog, and latest tweet.
You may visit https://developer.twitter.com/en/docs/authentication/oauth-1-0a/obtaining-user-access-tokens to read more about the 3-legged OAuth.
Although this tutorial is entitled “How to integrate Twitter Login API into your React app,” we cannot do this with React alone (unlike OAuth 2.0-based logins such as Facebook and Google). We need an Express server to serve as our backend.
The necessity of a server-side application stems from 1.) OAuth 1.0a protocol requirements and 2). two fundamental limitations of React applications.
OAuth 1.0a requires us to keep an API secret (a.k.a CONSUMER_SECRET) in our code (the one we kept earlier) to generate signatures for every OAuth call. The browser needs to download our code in full for it to run our React app. Regardless of how you minify or uglify the codebase, the API secret will be there for the world to see. We use Express as the server-side component that conceals this secret.
For the most part, our backend code is a just thin wrapper around the Twitter API’s to overcome the limitations discussed. We can analyze express/src/index.js and discuss the implementation.
We can easily see that the Oauth steps in React have counterparts in Express.
We see Step 1 at Lines 26 - 41, Step 3 at Lines 44 - 66, and the authenticated API resource access at Lines 69 - 80. We need not implement Step 2 anymore, as it is a simple browser redirect. Observe that we have direct access to oauth_token_secret, oauth_access_token, and oauth_access_token_secret here, unlike in React.
Line 6-16: If you are looking for the CONSUMER_SECRET, it is neatly and quietly tucked away inside lib/oauth-promise to initialize the oauth library. We will get back to the oauth library later.
The only data visible to React is the request token (oauth_token), which we will also use as our identity token. Lines 31 - 36 shows how we created a cookie out of the oauth_token. We do this for user identification on subsequent visits. We ensure that nothing else is in the cookie aside from the oauth_token.
On lines 33 - 35, we follow Tania Rascia’s recommendation on how to do cookie-based authentication in Single Page Applications, such as the one we have. As such:
Line 12-14: Where do we keep all the other tokens that need to persist during the OAuth dance? On line 14, we implement a naive and straightforward in-memory object that will survive the session jumps for the most part. The in-memory object storage works well in development machines (as long as you do not restart your Express server). It surprisingly works in serverless deployments, although lambda functions (such as those provided by AWS or Netlify) do not guarantee to keep in-memory states at all and thus may drop it anytime.
As this is a demonstration, we keep it simple to prevent unneeded complications that will distract us from integrating a Twitter login mechanism. We recommend using either a key-value store, a document store, or a database to keep these tokens for production systems.
At Line 9, we use the oauth library to spare us the agony and terror of writing the OAuth 1.0a protocol from scratch, with its crazy signature generation and cryptic Twitter response messages. Such is the pain that I experienced when I foolishly attempted to implement it by myself. I do not wish my worst enemies to experience such torment.
Line 18-55: We wrapped the oauth library nicely within lib/oauth-promise to deal with async and await calls instead of messy callbacks that seriously hurt the eyes.
Line 82 - 93: Logging out is a matter of expiring our cookie to force the user to request a new oauth_token.
For maximum security for our application, both React and Express need to reside in one site. Having them in one domain prevents a whole range of headaches such as CORS enabling and XHR cookie passing.
We achieve this in development by taking advantage of create-react-app’s proxy feature. A quick peek at react/package.json reveals the following:
Line 2-5: The proxy property tells create-react-app to reroute all paths to http://localhost:3000 if React is not able to handle such route. Port 3000 happens to be the default port that Express listens to, so if you are using default ports, there’s not much to do here.
Note that this only works in development. Deploying React and Express in one site for production is outside the scope of this tutorial.
We need Twitter to see our application, especially once the redirect happens after Step 2. Hosting our application locally is not enough; we need to expose the app to the outside world.
We run ngrok to listen to port 8080, which is React’s default development port.
ngrok http 8080
We take note of the URL (HTTPS version), as we will use it later.
We will need to export several environment variables for our application to run properly:
Once everything is set, we can now run both react and express on separate terminals. Note that you need to set the environment variables for both terminals.
cd react && npm start
cd express && npm start
As a final step, we need to register our ngrok URL. Proceed back to the Developer Portal. Go to your app > Settings > Authentication settings > Edit.
Time to view our app!
At last, we reach the exciting bit. Open your browser, and go to the ngrok URL (https://49d6c448c952.ngrok.io/). If fully working, you should see the following screens:
You can view a live demo here to compare: https://pensive-snyder-a1edac.netlify.app
You can view our source code for this tutorial at: https://github.com/QuodAI/tutorial-react-twitter-api-login