Let's make OAuth (like "Login with Google / Facebook / Github") integrated login/registration form in Node.js.
Firstly we'll make our project folder:
mkdir oauth-login && cd oauth-login
And then we should install necessary libraries:
npm install express auth-verify ejs
And our file structure will be like this:
|-- index.js
|-- package.json
|-- package-lock.json
|-- views/
|-- index.ejs
|-- profile.ejs
|-- node_modules/
Let's make our index.js file by preparing ejs and our web server
const express = require('express');
const path = require('path');
const app = express();
app.set("view engine", "ejs"); // using ejs
app.set("views", path.join(__dirname, "views"));
app.use(express.static(path.join(__dirname, "public")));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
const PORT = 3000;
app.listen(PORT, ()=>{
console.log(`Server running on ${PORT}...`);
});
And now we should make our index.ejs file and insert it to our web server as response to users/clients:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Login with Google</title>
<!-- Bootstrap 5 CDN -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
>
<style>
body {
background: #f8f9fa;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.card {
padding: 2rem;
border-radius: 1rem;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
text-align: center;
}
.google-btn {
background-color: white;
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px 20px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
transition: all 0.2s;
}
.google-btn:hover {
background-color: #f1f1f1;
}
.google-btn img {
width: 20px;
height: 20px;
}
</style>
</head>
<body>
<div class="card">
<h3 class="mb-3">Welcome Back 👋</h3>
<p class="text-muted">Sign in with your Google account</p>
<a href="/auth/google" class="google-btn mt-3 nav-link">
<img src="https://www.svgrepo.com/show/355037/google.svg" alt="Google logo" />
<span>Continue with Google</span>
</a>
</div>
</body>
</html>
And index.js we'll add index page:
app.get('/', (req, res)=>{
res.render('index');
});
And our web looks like this:
OAuth integration
Now we'll make real OAuth integrated login for getting user data from Google. Firstly we make connection to our google cloud for using Oauth.
You need make project in Google Cloud for this. So after getting client id and secret id we'll use auth-verify for connection:
const AuthVerify = require('auth-verify');
const auth = new AuthVerify({storeTokens: 'memory'});
// making connection with Google
const google = auth.oauth.google({
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
redirectUri: 'http://localhost:3000/auth/google/callback' // we'll get user data at this page
});
After making connection we'll send response to Google OAuth for getting user data for logging in system:
app.get('/auth/google', (req, res) => google.redirect(res));
And then we'll get user data by code which sent by Google to our web server:
app.get('/auth/google/callback', async (req, res)=>{
const code = req.query.code;
try {
const user = await google.callback(code); // code sent by Google
res.render('profile', {user});
} catch(err){
res.status(500).send("Error: " + err.message);
}
});
And our profile.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Profile</title>
<!-- Bootstrap 5 CSS CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-md-6">
<!-- Profile Card -->
<div class="card shadow-sm">
<div class="card-body text-center">
<!-- Profile Picture -->
<img src="<%= user.picture %>"
class="mb-3"
width="100" style="border-radius:50%"
alt="Profile Picture" >
<!-- User Info -->
<h4 class="card-title"><%= user.name %></h4>
<p class="text-muted mb-1"><%= user.email %></p>
<!-- Action Buttons -->
<a href="/edit-profile" class="btn btn-primary btn-sm me-2">Edit Profile</a>
<a href="/logout" class="btn btn-outline-danger btn-sm">Logout</a>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap 5 JS CDN -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
And the result:
Full codes of index.js:
const express = require('express');
const path = require('path');
const app = express();
const AuthVerify = require('auth-verify');
app.set("view engine", "ejs"); // using ejs
app.set("views", path.join(__dirname, "views"));
app.use(express.static(path.join(__dirname, "public")));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
const auth = new AuthVerify({storeTokens: 'memory'});
// making connection with Google
const google = auth.oauth.google({
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_SECRET_ID',
redirectUri: 'http://localhost:3000/auth/google/callback' // we'll get user data at this page
});
app.get('/auth/google', (req, res) => google.redirect(res));
app.get('/auth/google/callback', async (req, res)=>{
const code = req.query.code;
try {
const user = await google.callback(code);
// res.send(`
// <h2>Welcome, ${user.name}!</h2>
// <img src="${user.picture}" width="100" style="border-radius:50%">
// <p>Email: ${user.email}</p>
// <p>Access Token: ${user.access_token.slice(0, 20)}...</p>
// `);
res.render('profile', {user});
} catch(err){
res.status(500).send("Error: " + err.message);
}
});
app.get('/', (req, res)=>{
res.render('index');
});
const PORT = 3000;
app.listen(PORT, ()=>{
console.log(`Server running on ${PORT}...`);
});


Top comments (0)