I get the message Unknown authentication strategy "google" in the browser when I try to login with Google using passport.JS in my node.js and express app. I can't seem to figure out what I'm doing wrong. Here is my code. I've also read other posts but didn't find a working fix yet.
config\passport.js
const passport = require('passport');
const mongoose = require('mongoose')
const User = require('../Models/User')
const GoogleStrategy = require('passport-google-oauth20').Strategy
module.exports = function (passport) {
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: '/auth/google/callback',
},
async (accessToken, refreshToken, profile, done) => {
const newUser = {
googleId: profile.id,
displayName: profile.displayName,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
image: profile.photos[0].value,
}
try {
let user = await User.findOne({ googleId: profile.id })
if (user) {
done(null, user)
} else {
user = await User.create(newUser)
done(null, user)
}
} catch (err) {
console.error(err)
}
}
)
)
passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => done(err, user))
})
}
Routes\auth.js
const express = require('express')
const passport = require('passport')
const router = express.Router()
// @desc Auth with Google
// @route GET /auth/google
router.get('/google', passport.authenticate('google', { scope: ['profile'] }))
// @desc Google auth callback
// @route GET /auth/google/callback
router.get(
'/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
(req, res) => {
res.redirect('/')
}
)
// @desc Logout user
// @route /auth/logout
router.get('/logout', (req, res) => {
req.logout()
res.redirect('/')
})
module.exports = router
App.js
var createError = require('http-errors');
var express = require('express');
const dotenv = require('dotenv');
var path = require('path');
const passport = require("passport")
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const connectDB = require('./config/db')
const mongoose = require('mongoose');
const session = require("express-session")
const MongoStore = require('connect-mongo')(session)
const expressLayouts = require("express-ejs-layouts")
const port = 3000
// Load config
dotenv.config({ path: './config/config.env' })
//Connect to MongoDB
connectDB();
// passport config
require('./config/passport');
const app = express();
// view engine and EJS layout setup
app.use(expressLayouts)
app.set('layout', './layouts/layout')
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')))
//Passport middleware - Express Session
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection, collection: 'sessions' }),
})
app.use(passport.initialize());
app.use(passport.session());
// routes
app.use('/', require('./routes/homepage'))
app.use('/login', require('./routes/login'))
app.use('/users', require('./routes/users'))
app.use('/project', require('./routes/project'));
app.use('/about', require('./routes/about'));
app.use('/auth', require('./routes/auth'));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
module.exports = app;
I found my answer. I had to get rid of the
module.exports = function (passport)
in my passport.js file since I'm calling it through ``require('./config/passport')instead of
require('./config/passport')(passport)```