Unknown authentication strategy "google" - passport.js

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 ofrequire('./config/passport')(passport)```

Related

express-session is not saving cookies

I am using React with Nodejs and Express in making a login app. I want to only access my profile page when I am logged in. I use passport to authenticate and save cookies in my browser.
If I am not logged in, it should take me back to the home page, when I am logged in I should be able to access my profile.
Now when I also create an account, it should save a cookie in my browser so I can access my profile page, however, when I check my browser, there is no cookie for localhost.
There is something wrong with my code and I can't seem to figure it out. Can anyone help me here?
This is my server.js
const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const session = require("express-session");
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(
session({
secret: "This is our little secret",
resave: false,
saveUninitialized: false,
})
);
app.use(passport.initialize());
app.use(passport.session());
//connect to mongodb atlas
mongoose.connect(
"mongodb+srv://admin-darwin:test123#cluster0.nmhlm.mongodb.net/secretsDB",
{ useNewUrlParser: true, useUnifiedTopology: true }
);
//user schema
const userSchema = new mongoose.Schema({
username: String,
email: String,
password: String,
});
userSchema.plugin(passportLocalMongoose);
//user model
const User = mongoose.model("User", userSchema);
passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.get("/profile", (req, res) => {
if (req.isAuthenticated()) {
console.log("yes");
} else {
res.send("not authenticated");
}
});
// create user
app.post("/new", (req, res) => {
User.register(
{ username: req.body.username },
req.body.password,
(err, user) => {
if (err) {
console.log(err);
res.redirect("/new");
} else {
passport.authenticate("local")(req, res, () => {
res.send("ok");
});
}
}
);
});
app.listen(5000, () => {
console.log("server running on port 5000");
});

My Local Host is keep loading although my mongodb server is connected amd running

I am following the brad Traversy Nodejs Tutorial my server is connected and started also my Mongodb connection is running but localhost keep loading and not responding.
I have checked my URL for mongo connection also the password and username all are correct. I have also allow network access from all sources.
This was perfectly working before but now this keeps loading and loading
my db.js
const mongoose = require("mongoose")
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true
})
console.log(`MongoDB connected ${conn.connection.host}`)
} catch (err) {
console.error(err)
process.exit(1)
}
}
module.exports = connectDB
my app.js
const express = require("express")
const path = require("path")
const dotenv = require('dotenv')
const morgan = require('morgan')
const exphbs = require('express-handlebars')
const passport = require('passport')
const connectDB = require('./config/db')
const routes = require('./routes/index')
const session = require("express-session")
const MongoDBStore = require('connect-mongodb-session')(session);
const mongoose = require('mongoose')
const methodOverride = require('method-override')
//locad config
dotenv.config({ path: './config/config.env' })
connectDB()
//passport config
require('./config/passport')(passport)
const app = express()
const PORT = process.env.PORT || 5000
//body parser
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
//method override
// Method override
app.use(
methodOverride(function (req, res) {
if (req.body && typeof req.body === 'object' && '_method' in req.body) {
// look in urlencoded POST bodies and delete it
let method = req.body._method
delete req.body._method
return method
}
})
)
//logging
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'))
}
//handlebars helpers
const { formatDate, truncate, stripTags, select } = require('./helpers/hbs')
//Hnadlebars
app.engine('.hbs', exphbs({ helpers: { formatDate, truncate, stripTags, select }, defaultLayout: 'main', extname: '.hbs' }));
app.set('view engine', '.hbs');
//sessions
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUnitialized: false,
store: new MongoDBStore({
mongooseConnection: mongoose.connection
})
//cookie: { secure: true }
}))
//set passport middleware
app.use(passport.initialize())
app.use(passport.session())
//set global variable
app.use(function (req, res, next) {
res.locals.user = req.user || null
})
//static folder
app.use('/', express.static(path.join(__dirname, 'public')))
//Routes
app.use('/', routes);
app.use('/auth', require('./routes/auth'));
app.use('/stories', require('./routes/stories'));
//listen
app.listen(PORT, console.log(
`server is running in ${process.env.NODE_ENV} mode on port ${PORT}`
))
my ./routes/index.js
const express = require('express')
const router = express.Router()
const { ensureAuth, ensureGuest } = require('../middleware/auth')
const Story = require('../models/story')
//#desc Login/Landing Page
//#route GET/
router.get('/', ensureGuest, (req, res, next) => {
res.render("login", {
layout: "login"
})
})
//#desc Login/Landing Page
//#route GET/
router.get('/dashboard', ensureAuth, async (req, res, next) => {
console.log(req.user)
try {
const stories = await Story.find({ user: req.user._id }).lean() //plain Js object
res.render("dashboard", {
name: req.user.firstName,
stories
})
} catch (error) {
console.log('Stories error', error)
res.render('error/500')
}
})
module.exports = router
my browser
I have found if you're using middlewares then must call next function at the end this was the reason my page wasn't loading
The error was at //set global variable middleware

VueJs Web Applications is Failed Authenticate User

I creating e commerce project . I want to user must have account in order to proceed the checkout process . I am able to create new user with the database but the problem is even the user is login and click buy button ,Still it is showing message user must be login. I want once the user is login then user will be able to buy products..
Here is my app.js code .
'use strict';
var debug = require('debug');
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var { User } = require('./db');
var session = require('express-session');
var passport = require('./passport');
var routes = require('./routes/api/index');
//var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', require('./routes/api').route);
//app.use('/', routes);
//app.use('/users', users);
app.use(session({
secret: 'some very very secret thing',
resave: false,
saveUninitialized: true
}));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(passport.session());
app.post('/signup', (req, res) => {
User.create({
username: req.body.username,
password: req.body.password
}).then((user) => {
if (user) {
res.redirect('/signin.html');
}
}).catch((err) => res.send("ERROR CREATING USER"));
});
app.post('/signin', passport.authenticate('local', {
failureRedirect: '/signin.html',
// successRedirect: 'profile'
successRedirect: '/index.html'
}));
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
Here is the user.js code .
var route = require('express').Router();
var { User } = require('../../db');
var session = require('express-session');
var passport = require('../../passport');
route.use(session({
secret: 'some very very secret thing',
resave: false,
saveUninitialized: true
}));
route.use(passport.initialize());
route.use(passport.session());
route.post('/signup', (req, res) => {
User.create({
username: req.body.username,
password: req.body.password
}).then((user) => {
if (user) {
res.redirect('/signin.html');
}
}).catch((err) => res.send("ERROR CREATING USER"));
});
route.post('/signin', passport.authenticate('local', {
failureRedirect: '/signin.html',
// successRedirect: 'profile',
successRedirect: '../../index.html'
}));
route.get('/profile', (req, res) => {
//Available to only logged in people
// Data is different (each user sees own profile)
// console.log(req)
if (req.user) {
res.json(req.user);
} else {
res.send("YOU ARE NOT LOGGED IN");
}
});
exports = module.exports = route;
Here is the screen shot when I run the project for Login page ..
Here is screen shot even user is login still displaying message first you must login.

express-validator error -> TypeError: req.checkBody is not a function

I am using express-validator package to validate requested data.
According to these answer I also did change the order or package declaration and initialization
below is my server.js file
const express = require("express");
const session = require("express-session");
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);
const path = require('path');
const cookieParser = require("cookie-parser");
const bodyParser = require("body-parser");
const passport = require('passport');
const promisify = require('es6-promisify');
const expressValidator = require('express-validator');
const expressJwt = require("express-jwt");
const error_staus = 404;
const morgan = require('morgan');
const logger = require('./helper/logger');
const routes = require('./routes/index');
let server = "";
const bugsnag = require('bugsnag');
// import our configurations from config/tester.js file
const config = require("./config/tester").get(process.env.NODE_ENV);
require('./helper/passport');
require("./helper/translator");
// create our Express app
const app = express();
// view engine setup
app.set("views", `${__dirname}/views`);
app.set("view engine", "ejs");
// serves up static files from the public folder. Anything in app/ will just be served up as the file it is
app.use(express.static(path.join(__dirname, 'app')));
// Takes the raw requests and turns them into usable properties on req.body
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Exposes a bunch of methods for validating data. Used heavily on userController.validateRegister
app.use(expressValidator());
// Sessions allow us to store data on visitors from request to request
app.use(session({
secret: '123456',
key: '99785',
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));
app.use(session({
"secret": 'secret12345',
"resave": false,
"saveUninitialized": true
}));
// Passport JS is what we use to handle our logins
app.use(passport.initialize());
app.use(passport.session());
// promisify some callback based APIs
app.use((req, res, next) => {
req.login = promisify(req.login, req);
next();
});
// begin logger
app.use(morgan('dev', {
skip: function (req, res) {
return res.statusCode < 400
}, stream: process.stderr
}));
app.use(morgan('dev', {
skip: function (req, res) {
return res.statusCode >= 400
}, stream: process.stdout
}));
app.use('/', routes);
app.use(function(req, res, next){
logger.error('404 page requested');
res.sendStatus(error_staus);
});
// done! we export it so we can start the site in start.js
module.exports = app;
This is the userController.js
const mongoose = require('mongoose');
const User = mongoose.model('User');
const promisify = require('es6-promisify');
exports.loginForm = (req, res) => {
res.render('login', { title: 'Login' });
};
exports.registerForm = (req, res) => {
res.render('register', { title: 'Register' });
};
exports.validateRegister = (req, res, next) => {
req.sanitizeBody('name');
req.checkBody('name', 'You must supply a name!').notEmpty();
req.checkBody('email', 'That Email is not valid!').isEmail();
req.sanitizeBody('email').normalizeEmail({
gmail_remove_dots: false,
remove_extension: false,
gmail_remove_subaddress: false
});
req.checkBody('password', 'Password Cannot be Blank!').notEmpty();
req.checkBody('password-confirm', 'Confirmed Password cannot be blank!').notEmpty();
req.checkBody('password-confirm', 'Oops! Your passwords do not match').equals(req.body.password);
const errors = req.validationErrors();
if (errors) {
req.flash('error', errors.map(err => err.msg));
res.render('register', { title: 'Register', body: req.body, flashes: req.flash() });
return; // stop the fn from running
}
next(); // there were no errors!
};
Note : I am using express-validator version 3.1.2
When I check request object, in that object there is all methods of express-validator too.
But try to use that method I am getting req.checkBody is not a function error.
Can anybody help with these issue ?

Passport session not working

I'm trying to build a login system using express and passport.
As far as I know, I can use the req.user to access user id and correctly store their actions and req.isAuthenticated() would be true if Passport is working properly, however it isn't working.
For some reason, req.user is always undefined and req.isAuthenticated() is always false.
This is my app.js ->
const express = require('express');
const http = require('http');
const session = require('express-session');
const bodyParser = require('body-parser');
const passport = require('passport');
const route = require('./controllers/core'); **// CORE.JS**
const app = express();
app.set('view engine', 'ejs');
app.use('/css', express.static('css'));
app.use('/js', express.static('js'));
app.use('/themify', express.static('themify'));
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: false
//cookie: { secure: true }
}));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(passport.initialize());
app.use(passport.session());
app.use(route);
//core(app);
app.listen(3000);
And this is my core.js
const router = require('express').Router();
const passport = require('passport');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'pharmate',
dateStrings: 'date'
});
const urlencodedParser = bodyParser.urlencoded({ extended: false });
router.get('/index', function(req,res){
console.log(req.user);
});
router.post('/index', urlencodedParser, function(req,res){
var email = req.body.email;
var pass = req.body.password;
connection.query("SELECT `Pharmacy_ID`, `Email`, `Password` FROM `pharmacy` WHERE Email = ? AND Password = ?", [email, pass], function (error, results, fields) {
if (error) res.send(error);//throw error;
else{
if(results.length>0){
req.login(results[0], function(err){
res.redirect('index');
});
}
else{
res.redirect('login');
}
}
});
});
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
done(null, user);
});
module.exports = router;
Any help would be appreciated. Thanks in advance.
You should handle the authentication like:
app.post('/login',
passport.authenticate('local', {
successRedirect: '/secret',
failureRedirect: '/login',
})
);
Did you setup the passport local strategy ?

Resources