AMAN Vijay
AMAN Vijay

Reputation: 1

Unable to get userInformation on frontend while using google Oauth2 with jwt and passport.js

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

Answers (0)

Related Questions