Problem:
Encountering Error with Callback URI in Node.js Implementation of Google Login using google-auth-library
Details:
I am implementing Google login functionality in a Node.js application using the google-auth-library for OAuth 2.0 authentication. However, I am facing an error related to the callback URI when running the application on localhost.
Error Message:
The error pertains to the callback URI not being properly included in the request during the authentication process. As a result, the authentication flow encounters an error when attempting to redirect back to the specified callback URI
(http://localhost:5000/auth/google/callback).
Expected Outcome:
I expect the Google login functionality to seamlessly authenticate users using their Google accounts and redirect them back to my Node.js application after successful authentication, without encountering any callback URI errors.
Additional Information:
The Node.js application utilizes the google-auth-library for OAuth 2.0 authentication. The authorized JavaScript origin and redirect URI have been accurately configured in the Google Cloud Platform console as follows:
Authorized JavaScript Origins: http://localhost:3000
Authorized Redirect URI: http://localhost:5000/auth/google/callback
Despite these configurations, the callback URI issue persists, hindering the successful implementation of Google login functionality on localhost. Request for Assistance: I am seeking guidance on resolving the callback URI error and ensuring the successful implementation of Google login functionality in my Node.js application using the google-auth-library. Any insights, suggestions, or solutions would be greatly appreciated. Thank you!
Client client/src/App.js
import React from 'react';
function App() {
const handleLogin = () => {
window.location.href = "http://localhost:5000/auth/google";
};
return (
<div className="App">
<button onClick={handleLogin}>Login with Google</button>
</div>
);
}
export default App;
Node.js index.js
const express = require('express');
const cookieParser = require('cookie-parser');
const { OAuth2Client } = require('google-auth-library');
const app = express();
const port = 5000;
const googleClientId = 'MY_CLIENT_ID';
const oauthClient = new OAuth2Client(googleClientId);
app.use(cookieParser());
app.get('/auth/google', (req, res) => {
const state = generateStateToken();
res.cookie('state', state, { httpOnly: true });
const authUrl = oauthClient.generateAuthUrl({
access_type: 'offline',
scope: 'openid',
state: state,
});
res.redirect(authUrl);
});
app.get('/auth/google/callback', async (req, res) => {
const stateFromCookie = req.cookies.state;
const stateFromGoogle = req.query.state;
if (stateFromCookie !== stateFromGoogle) {
return res.status(400).send('State mismatch. Possible CSRF attack.');
}
try {
const { tokens } = await oauthClient.getToken(req.query.code);
const idToken = tokens.id_token;
res.redirect(`http://localhost:3000/callback?id_token=${idToken}`);
} catch (error) {
console.error('Error exchanging code for tokens:', error);
res.status(500).send('Error exchanging code for tokens');
}
});
function generateStateToken() {
return Math.random().toString(36).substring(2) + Math.random().toString(36).substring(2);
}
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});