Twitter Authentication with React and Node.js

Abhilash TU
4 min readJun 10, 2024

--

This guide will walk you through setting up Twitter authentication in a React application using a Node.js backend. The application will allow users to log in with their Twitter account, fetch their followers, and display them in the React app.

Prerequisites

  • Node.js and npm are installed on your machine.
  • Twitter Developer Account and a Twitter App set up.
  • Basic knowledge of JavaScript, React, and Express.js.
  • You need Basic tier Access to fetch Followers of related data, by default we only get Free tier Access.

Step 1: Setting Up the Twitter Developer Account

  1. Go to the Twitter Developer Portal.
  2. Create a new project and a new app within that project.
  3. Select Project → Settings → User authentication settings.
  4. Set the Type of App to Web App, Automated App Or Bot
  5. Setup Callback URL / REDIRECT URL to http://localhost:5000/callback.
  6. Set Website URL.
  7. Set up the OAuth 2.0 authentication settings with the callback URL: http://localhost:5000/callback
  8. In your app Keys and tokens, find and copy the following credentials:
  • In OAuth 2.0 Client ID and Client Secret
  • Client ID and Client Secret

Step 2: Setting Up the Backend Server

  1. Create a new directory for your project and initialize a new Node.js project:
mkdir twitter-auth-app cd twitter-auth-app npm init -y
  • Install the necessary packages:
npm install express cors dotenv axios twitter-api-s
  1. Create a .env file in the root directory and add your Twitter API credentials:
CLIENT_ID=your-twitter-api-key CLIENT_SECRET=your-twitter-api-secret-key
  • Create a server.js file and add the following code:
// This is the Express server that will handle OAuth flow
// and will receive the access token from Twitter
// and will also be responsible for fetching the user's followers
// and will be used by the client to make requests to Twitter API
//
// The server is created to separate the logic of handling the OAuth flow
// and the logic of fetching the user's followers and to avoid
// potential security issues that can arise from mixing the two
//
// The server is also responsible for setting up CORS to allow
// the frontend to make requests to the server

const { Client, auth } = require("twitter-api-sdk");
const express = require("express");
const axios = require("axios");
// const dotenv = require("dotenv");
const cors = require("cors");
let accessToken = "";
// dotenv.config();

const app = express();
app.use(cors());

const authClient = new auth.OAuth2User({
client_id: "ZURHVmZhM0FxYm0yWDZBNTZ6c2g6MTpjaQ",
client_secret: "489DpfNasqqX5m3UnLSGyrE5968gCBB8EufXavIMKWGvxXujhY",
callback: "http://localhost:5000/callback",
scopes: ["tweet.read", "users.read"],
});

const client = new Client(authClient);

const STATE = "my-state";

app.get("/callback", async function (req, res) {
try {
const { code, state } = req.query;
if (state !== STATE) return res.status(500).send("State isn't matching");
accessToken = (await authClient.requestAccessToken(code)).token
.access_token;
console.log("AccessToken: " + JSON.stringify(accessToken));

res.send(`
<html>
<body>
<p>You have been authenticated with this platform. You can close the window now.</p>
<script>
// Pass the access token and status to the parent window
window.opener.postMessage({ token: ${JSON.stringify(
accessToken
)}, status: "Login successful" }, "*");

// Close the window after a delay
setTimeout(() => {
window.close();
}, 3000); // 3 seconds delay
</script>
</body>
</html>
`);
} catch (error) {
console.log(error);
}
});

app.get("/login", async function (req, res) {
const authUrl = authClient.generateAuthURL({
state: STATE,
code_challenge_method: "s256",
});
console.log(authUrl);
res.redirect(authUrl);
});

app.get("/tweets", async function (req, res) {
const tweets = await client.tweets.findTweetById("20");
res.send(tweets.data);
});

app.get("/revoke", async function (req, res) {
try {
const response = await authClient.revokeAccessToken();
res.send(response);
} catch (error) {
console.log(error);
}
});

app.post("/followers", async (req, res) => {
try {
// const { accessToken } = req.body;

const userResponse = await axios.get("https://api.twitter.com/2/users/me", {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
});
const userId = userResponse.data.data.id;
console.log("User ID: " + userId);

const response = await axios.get(
`https://api.twitter.com/2/users/${userId}/followers`,
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
}
);

res.send(response.data.data);
} catch (error) {
console.error("Error fetching followers:", error);
res.status(500).send("Failed to fetch followers");
}
});

app.use(
cors({
origin: "https://localhost:3000",
})
);

app.listen(5000, () => {
console.log(`Go here to login: http://localhost:5000/login`);
});

Step 3: Setting Up the React Client

  1. Create a new React application in the twitter-auth-app directory:
npx create-react-app client cd client
  1. Install axios for making HTTP requests:
npm install axiosUpdate src/App.js with the following code:

Create a `server.js` file and add the following code:

'use client'
import axios from "axios";
import CustomCard from "../Components/Card";
import styles from "../page.module.css";
import { useEffect, useState } from "react";
export default function page() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [userID, setUserID] = useState('');
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [picture, setPicture] = useState('');

const [accessToken, setAccessToken] = useState(null);
const [loginStatus, setLoginStatus] = useState(null);
const [followers, setFollowers] = useState([]);

useEffect(() => {
const handleMessage = (event) => {
if (event.origin !== "http://localhost:5000") return;

const { token, status } = event.data;

if (token) {
setAccessToken(token);
setLoginStatus(status);
}
};

window.addEventListener("message", handleMessage);

return () => {
window.removeEventListener("message", handleMessage);
};
}, []);

const handleLogin = async () => {
try {
// const response = await axios.get('http://localhost:5000/login');
// const authUrl = response.data.url;
window.open("http://localhost:5000/login", '_blank', 'width=600,height=700');

} catch (error) {
console.error('Error initiating Twitter login', error);
}

};

const handleLogout = async () => {

};

const handleFetchEmail = async () => {

};

const handleFetchFollowers = async () => {
try {
const response = await axios.post("http://localhost:5000/followers", {
accessToken,
});
console.log(response.data)
} catch (error) {
console.error("Error fetching followers", error);
}
};

const handleFetchPosts = async () => {

};

const handleFetchPermissions = async () => {

};

return (
<main className={styles.main}>
<CustomCard >

<div className={styles.btnCont}>
<button className={styles.btn} onClick={handleLogin}>Login</button>
<button className={styles.btn} onClick={handleFetchFollowers}>Fetch Followers</button>
{/* <button className={styles.btn} onClick={handleLogout}>Logout</button>
<button className={styles.btn} onClick={handleFetchEmail}>Fetch Email</button>

<button className={styles.btn} onClick={handleFetchPosts}>Fetch Posts</button>
<button className={styles.btn} onClick={handleFetchPermissions}>User Permission</button> */}

</div>
</CustomCard>
</main>
);
}

Step 4: Running the Application

  1. Start the Backend Server:
cd twitter-auth-app node server.js
  1. Start the React Client: Open a new terminal window and run:
cd twitter-auth-app/client npm start

Conclusion

You have successfully set up Twitter authentication in a React application using a Node.js backend. Users can log in with their Twitter account, fetch followers, and display them in the React app. This setup provides a solid foundation for further enhancements, such as additional Twitter API interactions or improved user interface elements.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Abhilash TU
Abhilash TU

Written by Abhilash TU

0 Followers

Being curious about science and tech is more like a lifestyle, and I devote myself to it.

No responses yet

Write a response