Search code examples
javascriptnode.jsauthenticationoauthgoogle-oauth

Node JS Passport Google OAuth Not Authenticating


I followed the following document and tried to setup Google OAuth for my nodeJS application: https://cloud.google.com/nodejs/getting-started/authenticate-users

My oauth2.js code is as follows:

const express = require('express');
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;

function extractProfile (profile) {
    let imageUrl = '';
    if (profile.photos && profile.photos.length) {
        imageUrl = profile.photos[0].value;
    }
    return {
        id: profile.id,
        displayName: profile.displayName,
        image: imageUrl
    };
}
passport.use(new GoogleStrategy({
    clientID: <CLIENT ID as string>,
    clientSecret: <CLIENT SECRET as string>,
    callbackURL: 'http://<APP DOMAIN>/auth/google/callback'
}, (accessToken, refreshToken, profile, cb) => {
    cb(null, extractProfile(profile));
}));
passport.serializeUser((user, cb) => {
    cb(null, user);
});
passport.deserializeUser((obj, cb) => {
    cb(null, obj);
});
const router = express.Router();
function authRequired(req, res, next){
    if(!req.user){
        req.session.oauth2return = req.originalUrl;
        return res.redirect('/auth/login');
    }
    next();
}
function addTemplateVariables(req, res, next){
    res.locals.profile = req.user;
    res.locals.login = `/auth/login?return=${encodeURIComponent(req.originalUrl)}`;
    res.locals.logout = `/auth/logout?return=${encodeURIComponent(req.originalUrl)}`;
    next();
}

router.get(
    '/auth/login',
    (req, res, next) => {
        if(req.query.return) {
            req.session.oauth2return = req.query.return;
        }
        next();
    },
    passport.authenticate('google', {scope: ['email', 'profile']})
);

router.get('/auth/google/callback',
    passport.authenticate('google', {
        successRedirect: '/index',
        failureRedirect: '/'
    })
);

router.get('/auth/logout', (req, res)=>{
    req.logout();
    res.redirect('/');
});

module.exports = {
    extractProfile: extractProfile,
    router: router,
    required: authRequired,
    template: addTemplateVariables
};

And it seems like everything else is working fine. I am redirected to the Google OAuth Consent Screen, and after signing in, I am supposed to select ALLOW (to give permission). However, when I am redirected to /auth/google/callback, the passport.authenticate('google' ... part is not authenticating, and I get a 404 Not Found error (not a cannot GET error).

I know the redirecting is working properly because if I try

router.get('/auth/google/callback',
    function(req, res){
        res.redirect('/index');
    }
);

the app redirects without a problem.

What should I try? I'm guessing it's something to do with the token, but I have no idea what to check/fix.

Thank you so much in advance.


Solution

  • http://voidcanvas.com/googles-oauth-api-node-js/ I ended up using googleapis package, following the steps in the above link. It works like magic ;)