Can we remember the user outside a route in passport.js? - node.js

I'm creating a MEAN Stack food catalog application. Node.js gives me the user logged in, in my login route when I check for req.isAuthenticated(). But when I try to check later whether I'm still logged in, it gives req.user as undefined.
How do I make the user persist? I know I can use local storage but is there a better way?
var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
var passport = require('passport');
var mongoose = require('mongoose');
var LocalStrategy = require('passport-local');
var passportLocalMongoose = require('passport-local-mongoose');
app = express();
app.use(require('express-session')({secret:"timelord",resave:false,saveUninitialized:false}));
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(passport.session());
mongoose.set('useNewUrlParser', true);
mongoose.set('useUnifiedTopology', true);
mongoose.connect('mongodb://127.0.0.1:27017/delectabledb');
var UserSchema = new mongoose.Schema({name: String,
gender: String,
dob: String,
country:String,
phone: String,
email: String,
password: String,
username: String,
prof: String});
UserSchema.plugin(passportLocalMongoose);
var User = mongoose.model("User", UserSchema);
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.post('/loginUser', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
console.log(req.user) //returns false
if (err) { return next(err); }
if (!user) { res.send({code:"500"}); }
req.logIn(user, function(err) {
console.log(req.user) //returns true
if (err) { return next(err); }
res.send({code:"200", user:user});
});
})(req, res, next);
});
app.listen(3000, ()=>{
console.log("Running server on port 3000...");
});

Related

passport.authenticate('local', function (err, user, info) is not working

I'm having some issues with setting up passport. The information gets to the console.log(req.body). and the user is being saved in the mongodb database with all the salting and hashing
passport.authenticate is not woking while signing up new users. but
and Express sessions are not being created.
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const cors = require('cors');
const session = require('express-session');
const passport = require("passport");
const LocalStrategy = require("passport-local");
const passportLocalMongoose = require("passport-local-mongoose");
const findOrCreate = require("mongoose-findorcreate");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("public"));
app.use(
cors({
origin: true,
credentials: true,
optionsSuccessStatus: 200
}));
mongoose.set("strictQuery", false);
app.use(session({
secret: "our little secret.",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
mongoose.connect("mongodb://localhost:27017/blogDB");
const userSchema = new mongoose.Schema(
{
name: String,
username: String,
password: String,
posts: [{
title: String,
content: String,
timestamp: Date
}]
}
);
userSchema.plugin(passportLocalMongoose);
userSchema.plugin(findOrCreate);
const User = new mongoose.model("user", userSchema);
passport.use(new LocalStrategy(User.authenticate()));
// passport.use(User.createStrategy());
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
app.post("/signup", function (req, res) {
User.register(
{ name:req.body.name,
username:req.body.email },
req.body.password,
function (err, user) {
if (err) {
console.log(err);
} else {
res.send(user);
passport.authenticate('local', function (err, user, info) {
if (!err) {
console.log("authenticated");
}
})(req, res)
}
})
})
i have been searching the whole web tring to find a solution, tried a so many solutions but nothing worked

Level 1 authentication

Good day, Please help me find the error in my code for level one authentication I could create a database, register users and store in their inputs using body parser, but I couldn't login already registered users. the login page keeps loading till it tells me a connection error, please help me out
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require("mongoose");
const app = express();
app.use(express.static("public"));
app.set('view-engine', 'ejs');
app.use(bodyParser.urlencoded({
extended: true
}));
mongoose.connect("mongodb://localhost:27017/User", {useNewUrlParser: true});
const userSchema = ({
email: String,
password: String
});
const User = new mongoose.model("User", userSchema);
const users = []
app.get("/", function(req, res){
res.render("first.ejs");
});
app.get("/login", function(req, res){
res.render("login.ejs");
});
app.get("/register", function(req, res){
res.render("register.ejs");
});
app.post("/register", function(req, res){
const newUser = new User({
email: req.body.username,
password: req.body.password
});
newUser.save(function(err){
if (err) {
console.log(err);
} else {
res.render("home.ejs");
}
});
});
app.post("/login", function(req, res){
const username = req.body.username;
const password = req.body.password;
User.findOne({email: username}, function(err, foundUser){
if (err) {
console.log(err);
} else {
if (foundUser) {
if (foundUser.password === password) {
res.send("hi");
}
}
}
});
});
app.listen(3000, function() {
console.log("Server started on port 3000.");
});

username or password failure message in Passport.js

I have a login created in Express with the use of Passport.js. Now I have everything setup and when username and password are correct it will redirect to the user page. But now I want to show a message when the credentials are incorrect. Right now it leads to a blank page with an auto message of 'unauthorized'
This is my passport.js setup:
App.js:
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/homeapp');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
app.use(require('express-session')({
secret: 'testtest',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
var User = require('./models/User');
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Index.js
var express = require('express');
var router = express.Router();
var auth = require('../controller/AuthController.js');
router.get('/', auth.home);
router.get('/login', auth.login);
router.post('/login', auth.doLogin);
router.get('/logout', auth.logout);
module.exports = router;
Users.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var UserSchema = new Schema({
username: String,
password: String
}, {collection: 'userdata'});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', UserSchema);
AuthController.js:
var mongoose = require("mongoose");
var passport = require("passport");
var User = require("../models/User");
var userController = {};
userController.home = function(req, res) {
res.render('index', { user : req.user });
};
userController.login = function(req, res) {
res.render('login');
};
userController.doLogin = function(req, res){
passport.authenticate('local')(req, res, function(){
res.redirect('/');
});
};
userController.logout = function(req, res) {
req.logout();
res.redirect('/');
};
module.exports = userController;
You can do modification in your code like this :
userController.doLogin = function(req, res){
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login',
failureFlash: true })
passport.authenticate('local', { failureFlash: 'Invalid username or
password.' });
};
Setting the failureFlash option to true instructs Passport to flash an error message using the message given by the strategy's verify callback, if any. This is often the best approach, because the verify callback can make the most accurate determination of why authentication failed.
As ,i have seen you are using passport custom callback method for this you can do like this:
userController.doLogin = function(req, res){
passport.authenticate('local', function(err, user) {
if (err) { return next(err); }
if (!user) { return res.json('invalid credentials'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/');
});
})(req, res);
};

I keep getting Connot GET /auth/twitter/callback in my callbackURL when using passport. What am I doing wrong?

I have seen similar posts with this problem, but none of those answers seemed to fix my issue. Including the missing hyphen in a couple answers.
When I send the user to Twitter to get authenticated using Passport, the broswer says I have no GET handler for my callbackURL. I am super confused since I believe I do have it handled, but its not working.
In my app.js file I have:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var passport = require('passport');
var session = require('express-session');
app.set('views', './views');
app.set('view engine', 'jade');
app.use(express.static('public'));
app.use(express.static("node_modules/bootstrap/dist"));
app.use(express.static("node_modules/jquery/dist"));
app.use(express.static('img'));
app.use(require('express-session')({
secret:'prince', resave: false, saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
var authRouter = require('./admin/auth');
app.use("/admin/login", authRouter);
var frontPageFlow = require('./index');
app.get('/', frontPageFlow, function (req, res) {
res.render('index', {
title: "Crowd District"
});
});
In my Auth.js file I have:
var express = require('express');
var passport = require('passport');
var TwitterStrategy = require('passport-twitter').Strategy;
var router = express.Router();
module.exports = router;
router.get('/auth/twitter',
passport.authenticate('twitter'),
function (req, res) {
res.render('login')
});
router.get('/auth/twitter/callback',
passport.authenticate('twitter', {
successRedirect: '/',
failureRedirect: '/login'
}));
router.route('/')
.get(function (req, res) {
res.render("login");
})
.post(passport.authenticate('twitter', {
successRedirect: '/',
failureRedirect: '/admin/login'
})
);
passport.use(new TwitterStrategy({
consumerKey: 'Consumer key here',
consumerSecret: 'Consumer secret here',
callbackURL: 'http://localhost:9000/auth/twitter/callback'
},
function(token, tokenSecret, profile, cb) {
User.findOrCreate({ twitterId: profile.displayName }, function (err, user) {
if (err) { return cb(null, profile); }
if (!user){
user = new User ({
name: profile.displayName,
email: profile.emails[0].value,
username: profile.username,
provider: 'twitter'
});
user.save(function (err) {
if (err) console.log(err);
console.log("successful user entry!");
return done(err, user);
});
} else {
return done(err, user);
}
});
}
));
And my userModel.js
var mongoose = require('mongoose');
var express = require('express');
var router = express.Router();
module.exports = router;
var schemaOptions = {
collection: "users"
};
var schema = new mongoose.Schema({
id : String,
token : String,
displayName : String,
username : String
}, schemaOptions);
module.exports = mongoose.model('User', schema);
No matter what I do, or rearrange the order of operations, I continue to get in my callback:
Cannot GET /auth/twitter/callback?oauth_token=enfwejngfon2804&oauth_verifier=LK35h5988gieunrgbr4ghghi
Thank you very much in advance!
Your route paths are incorrect because you are using app.use("/admin/login", authRouter); which makes all routes in that file have a prefix '/admin/login', so instead of '/auth/twitter/callback', you code is expecting '/admin/login/auth/twitter/callback'. Get all your paths to line up and you'll be in better shape. I recommend avoiding mount prefixes when calling app.use. They just lead to this kind of confusion. Just use app.use(authRouter); and make your route paths absolute paths. They are much more straightforward to work with.

NodeJS: Passport authentication not working

I am using passport local for authentication and the login credentials don't get authenticated. I just get redirected to the failureRedirect. I don't even get the flash error.
Here is my login route:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var flash = require('connect-flash');
router.get('/', function(req, res, next) {
if(req.user){
return res.redirect('/profile');
}
var vm = {
title: 'Login',
error: req.flash('error')
};
res.render('login', { title: 'Place an order' });
});
router.post('/',
passport.authenticate('local', {
failureRedirect: '/login',
successRedirect: '/profile',
failureFlash: 'Invalid credentials'
}));
module.exports = router;
This is app.js:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var passport = require('passport');
var expressSession = require('express-session');
var flash = require('connect-flash');
var config = require('./config');
var routes = require('./routes/index');
var signup = require('./routes/signup');
var login = require('./routes/login');
var profile = require('./routes/profile');
var restrict = require('./auth/restrict');
var passportConfig = require('./auth/passport-config');
passportConfig();
mongoose.connect(config.mongoUri);
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
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(expressSession({
secret: 'themsec',
saveUninitialized: false,
resave: false
}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use('/', routes);
app.use('/signup', signup);
app.use('/login', login);
//app.use(restrict);
app.use('/profile', profile);
// 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: {}
});
});
module.exports = app;
Passport-config:
module.exports = function(){
var passport = require('passport');
var passportLocal = require('passport-local');
var userService = require('../services/user-service');
passport.use(new passportLocal.Strategy({username: 'email'},function(email, password, next){
userService.findUser(email, function(err, user){
if(err){
return next(err);
}
if(!user || user.password!= password){
return next(null, null);
}
next(null, user);
});
}));
passport.serializeUser(function(user, next){
next(null, user.email);
});
passport.deserializeUser(function(email, next){
userService.findUser(email, function(err, user){
next(err, user);
});
});
};
User services:
var User = require('../models/user').User;
exports.addUser = function(user, next){
var newUser = new User({
firstName: user.firstName,
lastName: user.lastName,
email:user.email.toLowerCase(),
password: user.password,
});
newUser.save(function(err){
if(err)
return next(err)
next(null);
});
};
exports.findUser = function(email, next){
User.findOne({email:email.toLowerCase()}, function(err, user){
next(err, user)
});
};
User model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userService = require('../services/user-service');
var userSchema = new Schema({
firstName: {type: String, required: true},
lastName: String,
email: {type: String, required: true},
password: {type: String, required: true},
created: {type: Date, default: Date.now}
});
userSchema.path('email').validate(function(value, next){
userService.findUser(value, function(err, user){
if(err){
console.log(err);
return false;
}
next(!user)
});
}, 'That email is already in use');
var User = mongoose.model('User', userSchema);
module.exports = {
User:User
};
Someone please help me, I am turning mad with frustration. I am new to Node.
Edit: I have removed the code that would lead to an infinite loop if the user logged-in, however, I still cannot login.

Resources