How to do Twitter authentication with React and RESTful API

Ivan Vasiljevic
9 min readSep 25, 2017

--

Photo by Eric Fischer on flickr

In this tutorial we will integrate Twitter authentication with a RESTful API created using Express.js. On the backend side we will use MongoDB as a database, Node.js and Express.js. On the frontend side we will use React to implement simple application that will enable us to show the entire registration and login workflow. A similar process can be applied to any single page application (SPA) and the RESTful API backend.

Authentication workflow

In this section we will describe the process of the Twitter authentication. The detailed explanation of the whole process can be found in Twitter documentation.

The process of Twitter authentication is shown in the figure 1.

Figure 1. Twitter authentication process

Creating a new Twitter application

To make it possible for users to log into our application with their Twitter accounts, we need to register a new Twitter application on Twitter. This is a necessary step for getting the key and the secret code required for all future communication between our application and Twitter. This is necessary for our application to identify itself to Twitter.

We can register a new Twitter application here, by pressing Create New App button.

Next, we need to enter our application details.

  • Name a unique name (one that no one else has used for their Twitter application).
  • Description — short description of our application. This can be changed later.
  • Website — website where application will be hosted. If we currently don’t have that, we can put placeholder for the time being. In our case, we will write here: https://github.com/GenFirst/react-node-twitter-login.
  • Callback URL — URL to which user will be redirected if authentication process was successful. If this field is not populated the user will get PIN when authorize the application, so the process will not be finished automatically. You must enter a callback URL, even when we are not using it.

After we have registered our application, we will get a screen where we can find the key and the secret of our Twitter application, the tab Keys and Access Tokens, but also adjust application settings.

Our application needs access to user email, and that is not enabled by default. To change that, on our Twitter application page, we need to supply privacy policy and terms of service URLs. These two URLs can be entered on the Settings tab.

After that we need to open Permissions tab.

On the bottom of the page we can find the check box that we need to mark, Request email addresses from users. Mark it and press button Update Settings. Our Twitter application is now ready.

Client setup — React

In this section, we will create a client application in React. Through the application, we will demonstrate how to implement Twitter authorization in React. For setting up the project we have used Create React App tool. On project site can be found great documentation how to install the tool. So we will skip that part.

A new application can be created with the command:

create-react-app frontend

After that we need to install only dependency that we need for this example:

npm i react-twitter-auth -S

Package react-twitter-auth is a React component that we will use to authenticate users with their Twitter accounts.

React application

The entire client application is in App.js file. Firstly, we will explain the constructor. In the constructor we are initializing state, and by default user is not authenticated.

Next is the render method. If the user is authenticated we will show its email and the button for logging out. If, however the user is not authenticated, we will show the button for Twitter sign up by using TwitterLogin component. The component itself is parametrized with 4 properties:

  • requestTokenUrl — URL of the endpoint where component can request request_token from the server
  • loginUrl — URL of the endpoint where component can send verification_code to finish the authentication process
  • onSuccess — function that will be called if Twitter authentication is successful. As first parameter this function receives original response from the backend application. In our case we will extract the token and the user object from response in this function
  • onFailure — function that will be called if Twitter authentication is not successful. As first parameter this function receives an error. In our case we will show error in the new dialog

The only method left is logout. We need to remove any data about the user and the token. Also, we want to set the flag that user is not authenticated anymore.

Backend setup — Node.js, Express.js

Dependencies

For creating RESTful API we will use Express.js. Parsing incoming request bodies in a middleware before our handlers will be done by body-parser. Handling JWT will be done by express-jwt and jsonwebtoken. Authentication will be done with passport, and for Twitter authentication we will use passport-twitter-token library. As database, we will use MongoDB, and Mongoose to communicate with the database. Last but not least, we will need to enable CORS on our server and for that we will use cors library.

Database model

User information will be persisted in the database. We have only one entity to model and that is user. We are only interested in the user’s email information from their Twitter profile, so that is the only thing that we will include. Also, we will persist the user access token and Twitter profile id.

An interesting thing to notice here, is that by putting select to false in twitterProvider object, we exclude twitterProvider field in result of queries by default. To get user with twitterProvider field, we need to specify explicitly in the query that we want that.

In UserSchema we have to add one static method that will be used for creating a new user, if the user doesn’t exist already. That method is upsertTwitterUser.

What we try to do in this method, is to find the user by their Twitter profile id. If we find a user with a matching Twitter profile id, that means that the user already has an account, which is associated with their Twitter profile. In that case we don’t need to do anything here. If we haven’t found the user, we will create a new user and save it in the database.

Passport configuration

A passport is authentication middleware for Node.js. It’s extremely flexible and modular. In this project, we will use passport-twitter-token, the Passport strategy for authenticating with Twitter access tokens using the OAuth API. There is also the passport-twitter library that contains a strategy for Twitter authentication, but this library is not suitable for RESTful API. It is better suited for Express.js applications which are used with some server rendering library.

The code for initialization of Passport with Twitter strategy looks like this:

To initialize the strategy we need to supply our Twitter application key and secret. We need users email, so we will set includeEmail to true. The key and the secret will be used to identify our application. The last parameter is a verify callback function. In our case this function calls the static method upsertTwitterUser from User model, which will check if the given user exist, and if not, create one.

Token handling

In our example, we will create JSON Web Token(JWT). We will use the user’s ID to create a token. The token will be signed and sent to the frontend. For creating JWT we will use jsonwebtoken library.

In the createToken function, we are getting user (auth) as function argument, and use the id to create a token. In this case we are using my-secret as private key; in production, we should use either the secret for HMAC algorithms, or the PEM encoded private key for RSA and ECDSA as stated in the library documentation. The generateToken function has request and response, and because of that it has access to the current user. So we will generate a token and put it in the request object. sendToken is a function that will take the token from request object and put it in the header.

For validation of the JWT on every frontend request, we will use express-jwt. How do we use express-jwt? If the token is valid, req.auth will be set with the decoded JSON object. The authenticate function does exactly that:

Property secret should have the same value as in the createToken function. By setting requestProperty we have the changed property name into a name which we will put into the decoded JSON object. The property getToken is a function that is used to extract a token from the request, and in our case the token is in the header x-auth-token.

Authentication flow

So, by now, we have all building blocks. We have to connect all our blocks in the system that will do the Twitter authentication. We will add two end points that are important for Twitter authentication:

  • end point for getting request_token — `/auth/twitter/reverse`
  • end point for authorization — `/auth/twitter`

The first end point is used for request_token from Twitter. When the end point get request for new request_token, it is sending a request to Twitter for new request_token. Response from Twitter is processed. Response is not formated as JSON object so we need to transform it to JSON object and send it back to the client that has requested request_token.

The second end point expects to get an oauth_verifier in the request. The oauth_verifier is then send to Twitter so that we can get an oauth_token and an oauth_token_secret from Twitter. These two parameters are then added to request and send to next middleware. Next middleware is passport authentication strategy for Twitter that will get user information from Twitter. There are two more middlewares on this end point, they will create our server token and return that together with user information as a response.

CORS

Currently, we have two applications, React application and Node.js/Express.js application, hosted on two servers. If we don’t set up CORS, our React application will not be able to communicate with the backend. To enable CORS on our backend, we will use the Node.js library cors.

By setting origin to true, we have allowed any origin to access the resource. methods is used to control Access-Control-Allow-Methods CORS header, and with this string we have allowed almost all HTTP methods. With the property credentials we are controlling the Access-Control-Allow-Credentials CORS header. The last, and very important property, exposedHeaders, is used to indicate which headers can be exposed as part of the response. If we haven’t set this property, the client library would ignore our custom header with user token.

HTTPS — make sure you use it

You MUST use HTTPS in production!

In this demo we will work on our local machine and we will NOT use HTTPS — but you MUST use HTTPS in production. Without it, all API authentication mechanisms are compromised.

You have been warned.

Conclusion

Congratulations! You now have a fully functional example of Twitter authentication. We have created a React application that can communicate with RESTful API and authenticate a user with Twitter account. We have also created a Node.js/Express.js application that exposes a RESTful API for that purpose.

The complete source code from this project can be found at the following GitHub repository:

I hope you have enjoyed this tutorial, and learned a thing, or two. There is much more to be done, but this should get you started.

If you have any questions feel, free to contact me on Twitter @robince885 or in the comments below. You can find more information about me on LinkedIn:

I would like to thank @vdimitrieski for his help and support. Feel free to contact him as well. Some more information about him you can find on his LinkedIn:

--

--

Ivan Vasiljevic

Enthusiastic software engineer with 5+ years of experience in web development and home automation | http://bit.ly/2LZoPsi