Implementing OAuth 2.0 in a React Application with Express.js
In today's digital landscape, securing applications and managing user authentication has become crucial. OAuth 2.0 is a widely adopted authorization framework that allows third-party services to exchange user information without sharing sensitive credentials. In this article, we'll delve into implementing OAuth 2.0 in a React application with an Express.js backend. We’ll cover definitions, use cases, and provide actionable insights with clear code examples to help you get started.
What is OAuth 2.0?
OAuth 2.0 is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service. Unlike traditional authentication methods where users share their passwords, OAuth 2.0 allows users to authorize applications to act on their behalf without sharing their credentials.
Key Concepts of OAuth 2.0
- Resource Owner: Typically the user who grants access to their data.
- Client: The application requesting access to the resource owner's data.
- Authorization Server: The server that authenticates the resource owner and issues access tokens to the client.
- Resource Server: The server hosting the protected resources, which accepts and verifies access tokens.
Use Cases for OAuth 2.0
Implementing OAuth 2.0 is particularly beneficial in scenarios such as:
- Third-party app integrations (e.g., social logins).
- Mobile applications needing access to user accounts.
- APIs requiring secure user data access without exposing credentials.
Setting Up Our Project
To implement OAuth 2.0 in a React application with Express.js, we will create a simple application that uses GitHub as the OAuth provider. Here’s how to set it up:
Step 1: Create a New React Application
npx create-react-app oauth-demo
cd oauth-demo
Step 2: Set Up Express.js Backend
Create a new directory for the server:
mkdir server
cd server
npm init -y
npm install express cors axios dotenv express-session passport passport-github
Step 3: Configure the Express Server
Create a file named server.js
:
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const session = require('express-session');
const passport = require('passport');
const GitHubStrategy = require('passport-github').Strategy;
const app = express();
app.use(cors({ origin: 'http://localhost:3000', credentials: true }));
app.use(session({ secret: 'your_secret_key', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new GitHubStrategy({
clientID: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
callbackURL: 'http://localhost:5000/auth/github/callback'
}, (accessToken, refreshToken, profile, done) => {
return done(null, profile);
}));
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((obj, done) => {
done(null, obj);
});
app.get('/auth/github', passport.authenticate('github'));
app.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/' }),
(req, res) => {
res.redirect('http://localhost:3000'); // Redirect to React app
}
);
app.get('/api/user', (req, res) => {
res.json(req.user);
});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Step 4: Add Environment Variables
Create a .env
file in the server directory and add your GitHub credentials:
GITHUB_CLIENT_ID=your_client_id
GITHUB_CLIENT_SECRET=your_client_secret
Step 5: Integrate with React
In your React app, install Axios for making requests:
npm install axios
Now, implement the login functionality. Update src/App.js
:
import React, { useEffect, useState } from 'react';
import axios from 'axios';
function App() {
const [user, setUser] = useState(null);
useEffect(() => {
axios.get('http://localhost:5000/api/user', { withCredentials: true })
.then(response => {
setUser(response.data);
})
.catch(error => console.error(error));
}, []);
const handleLogin = () => {
window.open('http://localhost:5000/auth/github', '_self');
};
return (
<div>
<h1>OAuth 2.0 with React and Express</h1>
{user ? (
<div>
<h2>Welcome, {user.displayName}</h2>
<img src={user._json.avatar_url} alt="Profile" />
</div>
) : (
<button onClick={handleLogin}>Login with GitHub</button>
)}
</div>
);
}
export default App;
Step 6: Test Your Application
-
Start your Express server:
bash node server/server.js
-
Start your React application:
bash npm start
-
Navigate to
http://localhost:3000
in your browser and click the "Login with GitHub" button. You should be redirected to GitHub to authorize your application.
Troubleshooting Common Issues
- CORS Errors: Ensure your Express server allows CORS from your React app.
- Token Expiry: If access tokens expire, handle refresh tokens in your application for a smoother user experience.
- Environment Variables: Ensure your environment variables are correctly set up for your GitHub application.
Conclusion
Implementing OAuth 2.0 in a React application with an Express.js backend enhances user experience by allowing secure, token-based authentication. This guide covered the essential steps to set up your application, demonstrating how to utilize GitHub as an OAuth provider. By following these instructions, you can create a secure and scalable authentication system for your web applications. With the foundation laid, feel free to explore and expand your application further, integrating more features and providers as needed. Happy coding!