Reputation: 1
I am using MERN stack for my project. Currently i am unable to display userinformation when sign in with google, I am able to save the data on database when i am signin locally and through google,but still can't fetch information when doing sign in with google, I am getting the information when i sign in locally. I'm stuck trying to send the JWT back to the frontend after a user logs in with Google OAuth and store it in localStorage.
I am attaching my routes and controller here- Here is my googleRoutes -
const express = require('express');
const googlerouter = express.Router();
const jwt = require('jsonwebtoken');
const passport = require('../controllers/googleController');
const axios = require('axios');
const jwtSecret = process.env.jwtSecret;
const clientUrl = process.env.CLIENT_URL;
// Route for initiating the OAuth 2.0 flow
googlerouter.get('/auth/googleauth', passport.authenticate('google', { scope: ['profile', 'email'], session: false }));
// Callback route for handling the authorization code and exchanging it for an access token
googlerouter.get('/auth/google/callback', async (req, res) => {
try {
const code = req.query.code;
const { data } = await axios.post('https://oauth2.googleapis.com/token', null, {
params: {
code: code,
client_id: process.env.GOOGLE_CLIENT_ID,
client_secret: process.env.GOOGLE_CLIENT_SECRET,
redirect_uri: 'http://localhost:5000/auth/google/callback',
grant_type: 'authorization_code'
}
});
const accessToken = data.access_token;
// access token to fetch user information
const { data: userInfo } = await axios.get('https://www.googleapis.com/oauth2/v3/userinfo', {
headers: {
Authorization: `Bearer ${accessToken}`
}
});
console.log('User information from Google:', userInfo);
const token = jwt.sign({ userInfo }, jwtSecret);
res.cookie('x-auth-cookie', token);
res.header('token', token);
res.redirect(`${clientUrl}/dashboard`);
} catch (error) {
console.error('Error exchanging authorization code for access token:', error);
res.status(500).send('Error exchanging authorization code for access token');
}
});
// For forwarding the request to Google authentication
googlerouter.get('/auth/google', async (req, res) => {
try {
const response = await axios.get('https://accounts.google.com/o/oauth2/v3/auth', {
params: req.query,
});
console.log('Google Auth response:', response.data);
res.send(response.data);
} catch (error) {
console.error('Google Auth error:', error.message);
res.status(500).send('Google Auth failed');
}
});
module.exports = googlerouter;
This is googleController -
const passport = require('passport');
const { Strategy: GoogleStrategy } = require('passport-google-oauth20');
const User = require('../model/User');
const { v4: uuidv4 } = require('uuid');
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: `${process.env.SERVER_URL}/auth/google/callback`,
proxy: true,
},
async (accessToken, refreshToken, profile, done) => {
try {
const existingUser = await User.findOne({ email: profile.emails[0].value });
if (existingUser) {
existingUser.googleId = profile.id;
existingUser.avatarUrl = profile.photos[0].value;
existingUser.verified = true;
await existingUser.save();
return done(null, existingUser);
} else {
const newUser = await new User({
firstname: profile.name.givenName,
lastname: profile.name.familyName,
email: profile.emails[0].value,
googleId: profile.id,
password: profile.id, // Google users don't have a password
verified: true,
Token: [{ token: uuidv4() }],
date: Date.now(),
avatarUrl: profile.photos[0].value,
}).save();
return done(null, newUser);
}
} catch (err) {
console.log(err);
return done(err);
}
},
),
);
module.exports = passport;
This is the userInfo Controller -
const getUserInfo = async (req, res) => {
try{
const userId = req.userId;
const user = await User.findById(userId);
if (!user) {
return res.status(404).json({ success: false, message: 'User not found' });
}
const userInfo = {
firstname: user.firstname,
lastname: user.lastname,
email: user.email,
avatarUrl: user.avatarUrl,
isAdmin: user.isAdmin,
};
res.status(200).json(userInfo);
}
catch(error){
console.error('Error fetching user information:', error);
res.status(500).json({ success: false, error: 'Server Error' })
}
};
And this is the frontend hook for fetching the data -
const authToken = localStorage.getItem('token');
useEffect(() => {
const fetchUserDetails = async () => {
try {
if (!authToken) {
return;
}
const response = await axios.get(`${SERVER_URL}/api/auth/userinfo`, {
headers: {
Authorization: `Bearer ${authToken}`,
},
});
const userData = response.data;
setUser(userData);
console.log(userData);
localStorage.setItem('user', JSON.stringify(userData));
} catch (error) {
console.error('Fetch user details error:', error.message);
}
};
fetchUserDetails();
}, [authToken]);
Upvotes: 0
Views: 38