Passport authentication doesnot seems to be working - node.js

This is my MiddleWare for Passport.js the issue i am getting here i cant logged in getting no errors, register route is working successfully i am entering the Right Credentials and everything from my view is great but i am not redirecting to anywhere i tried i am getting http:500 error and getting NO Select query where username='username' and password='password'
//Passport config
require('./config/passport')(passport)
//Passport MiddleWare
app.use(passport.initialize());
app.use(passport.session());
This is my passport.js file code
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
var bcrypt = require('bcryptjs');
module.exports = function (passport) {
passport.use(new LocalStrategy(function (username, password, done) {
models.User.findOne({
where:{username: username}
}.then(function (err,user) {
if(err) console.log(err);
if (!user) {
return done(null, false, {message: 'No user found!'});
}
bcrypt.compare(password, user.password, function (err, isMatch) {
if (err)
console.log(err);
if (isMatch) {
return done(null, user);
} else {
return done(null, false, {message: 'Wrong password.'});
}
});
})
)
}));
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
}
this is my login method in route
/*
*Post Login
*/
router.post('/login',function(req,res,next){
passport.authenticate('local',{
successRedirect:'/',
failureRedirect:'/admin/pages',
failureFlash:true
})(req,res,next);
})
This is my user.js
var express=require('express');
var router=express.Router();
var User = require('../models/user');
var models=require('../models');
var passport=require('passport');
var bcrypt=require('bcryptjs');
//Get Register
router.get('/register',function(req,res){
res.render('register',{
title:'Register'
})
});
/*
* Register Post
*/
router.post('/register',function(req,res){
var name=req.body.name;
var email=req.body.email;
var username=req.body.username;
var password=req.body.password;
var password2=req.body.password2;
models.User.findOne({
where:{username:username}
}).then(function(copyuser){
if(copyuser){
console.log('User already exist');
redirect('/users/login');
}
else{
var user={
name: name,
email: email,
username: username,
password: password,
admin: 0
};
// res.json(user);
bcrypt.genSalt(10,function(err,salt){
bcrypt.hash(user.password,salt,function(err,hash){
user.password=hash;
models.User.create(user).then(function(user){
res.json(user);
})
console.log('You are now registered');
res.redirect('/admin/pages')
})
})
}
})
})
/*
* Get Login
*/
router.get('/login',function(req,res){
if(res.locals.user) res.redirect('/');
res.render('login',{
title:'log in'
})
})
/*
*Post Login
*/
router.post('/login',function(req,res,next){
passport.authenticate('local',{
successRedirect:'/',
failureRedirect:'/admin/pages',
failureFlash:true
})(req,res,next);
})
//Exports
module.exports=router;

Related

How to code login (passport) authentication for two different users types? Node.js

I am new to Node.js.
For my application, I have two different type of users being doctors and patient. Currently, I been coding for the login and registration for patients and it works. I starting to code the login for the doctors and it doesn't seem to be working. Below is the passport.js. I watched a video (https://www.youtube.com/watch?v=6FOq4cUdH8k&ab_channel=TraversyMedia) to learn how to code the login and registration.
I think the issue is within the passport.js, I'm not really sure how to code it, when it comes to the second user.
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');
const Patient = require('../models/patients');
module.exports = function(passport) {
passport.use(
new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
Patient.findOne({
email: email
}).then(patient => {
if (!patient) {
return done(null, false, { message: 'That email is not registered' });
}
bcrypt.compare(password, patient.password, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
return done(null, patient);
} else {
return done(null, false, { message: 'Password is incorrect' });
}
});
});
})
);
passport.serializeUser(function(patient, done) {
done(null, patient.id);
});
passport.deserializeUser(function(id, done) {
Patient.findById(id, function(err, patient) {
done(err, patient);
});
});
const Doctor = require('../models/doctors');
module.exports = function(passport) {
passport.use(
new LocalStrategy({ usernameField: 'email' }, (demail, dpassword, done) => {
Doctor.findOne({
demail: demail
}).then(doctor => {
if (!doctor) {
return done(null, false, { message: 'That email is not registered' });
}
bcrypt.compare(dpassword, doctor.dpassword, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
return done(null, doctor);
} else {
return done(null, false, { message: 'Password is incorrect' });
}
});
});
})
);
passport.serializeUser(function(doctor, done) {
done(null, doctor.id);
});
passport.deserializeUser(function(id, done) {
Doctor.findById(id, function(err, doctor) {
done(err, doctor);
});
});
}}:
This is my doctor.js in route
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
const Doctor = require('../models/doctors');
router.get('/doctorregister', (req, res) => res.render('Doctorregister'));
router.get('/doctorlogin', (req, res) => res.render('Doctorlogin'));
module.exports = router;
router.post('/doctorregister', (req, res) => {
const { dname, dqualification, dlocation, dpractice, demail, dmobileno, dpassword, dpassword2 } = req.body;
let errors = [];
if (!dname|| !dqualification || !dlocation || !dpractice || !demail || !dmobileno || !dpassword || !dpassword2) {
errors.push({ msg: 'Please enter all fields' });
}
if (dpassword != dpassword2) {
errors.push({ msg: 'Passwords do not match' });
}
if (dpassword.length < 6) {
errors.push({ msg: 'Password must be at least 6 characters' });
}
if (errors.length > 0) {
res.render('doctorregister', {
errors,
dname,
dqualification,
dlocation,
dpractice,
demail,
dmobileno,
dpassword,
dpassword2
});
} else {
Doctor.findOne({ demail: demail }).then(doctor => {
if (doctor) {
errors.push({ msg: 'Email already exists' });
res.render('register', {
errors,
dname,
dqualification,
dlocation,
dpractice,
demail,
dmobileno,
dpassword,
dpassword2
});
} else {
const newDoctor = new Doctor({
dname,
dqualification,
dlocation,
dpractice,
demail,
dmobileno,
dpassword,
});
//hashing password in the database
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newDoctor.dpassword, salt, (err, hash) => {
if (err) throw err;
newDoctor.dpassword = hash;
newDoctor.save()
.then(doctor => {
req.flash('success_msg', 'You are now registered and can log in')
res.redirect('/doctors/doctorlogin');
})
.catch(err => console.log(err));
});
});
}
});
}
});
router.post('/doctorlogin', (req,res, next) => {
passport.authenticate('local', {
successRedirect: '/doctordashboard',
failureRedirect: '/doctors/doctorlogin',
failureFlash: true
})(req, res, next);
});
router.get('/logout', (req, res) => {
req.logout();
req.flash('You are logged out');
res.redirect('/doctors/doctorlogin');
});
The two different type of users should be different through the user Schema if you are using mongoose and mongoDB as Travesty-Media uses in some of his videos, and through the permissions in different sections of your web app.
Use the same passport code that you have used for the patient user and it works. Passport takes the user info and turns it into a Bearer auth token and sends it to the client, and then when it receives it from the client it decodes it to see what kind of user is logging in...
Different users have different info but same Passport logic, even if there are 2 different patient-users. So the logic from patient to doctor regarding the Passport is the same.
If you want the patient to have access to different routes of your app, you need to insert a middleware to that route to check if the type of user is the same with what you want it to be, but after passport has got the info from the token it has received from the client side.

NodeJS-PassportJS Giving The Certain Password

I am making a admin which will request just for a certain passport.
But when I type it I cannot log in ? How can I solve it ?
const mongoose = require('mongoose');
const UserSchema = mongoose.Schema({
password:{
type: String,
required: true
}
});
const User = module.exports = mongoose.model('User', UserSchema);
In my command line, I created a users collectin and inserted a password:'sifre'
This is my password.js :
const LocalStrategy = require('passport-local').Strategy;
const User = require('../models/user');
const config = require('../config/database');
const bcrypt = require('bcryptjs');
module.exports = function(passport){
// Local Strategy
passport.use(new LocalStrategy(function(password){
let query = {password:password};
User.findOne(query, function(err, user){
if(err) throw err;
if(!user){
return done(null, false, {message: 'No user found'});
}
/*Also I have tried:
// Match Username
let query = {username:username};
User.findOne(query, function(err, user){
if(err) throw err;
if(!user){
return done(null, false, {message: 'No user found'});
} */
/* to understand if it is about user name. Even I added username to models, db.collections
and other code pages but I couldnt solve. Because again
I couldnt reflect the models to db, I think.*/
// Match Password
bcrypt.compare(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, user);
} else {
return done(null, false, {message: 'Wrong password'});
}
});
});
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
}
Also this is my user.js:
const express = require("express");
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
let User = require('../models/user');
// Register Form
router.get('/login', function(req, res){
const password = req.body.password;
req.checkBody('password', 'Password is required').notEmpty();
let errors = req.validationErrors();
res.render('login');
});
router.post('/login', function(req, res, next){
passport.authenticate('local', {
successRedirect:'/',
failureRedirect:'/users/login',
failureFlash: true
})(req, res, next);
});
// logout
router.get('/logout', function(req, res){
req.logout();
req.flash('success', 'You are logged out');
res.redirect('/login');
});
module.exports = router;
And also this is my command line
db.createCollection('users');
...
db.users.insert{(password:'123'});
...
So how can I implement the inserted password to these code blocks. I cannot understand why it is not working. For now I dont get any errors but when I type that inserted password, I cannot move to user page.
Edit:
bcrypt.compare(password, user.password, function(err, isMatch){
console.log("asd");
if(err) throw err;
if(isMatch){
return done(null, user);
} else {
return done(null, false, {message: 'Wrong password'});
}
});
});
}));
This part is not working.(which is in passport.js)
Also I cannot entegrate the module(user.js) o my mongodb.

PassportJS Local Strategy not working Withh MongoDB

I'm trying to get a handle on user authentication with PassportJS, and I cannot get it to work my database setup.
I'm using MongoDB without Mongoose, and I can't get the LocalStrategy module to work.
Hopefully my database queries aren't too cumbersome to read.
Local Strategy:
passport.use(new LocalStrategy(
function(username, password, done) {
//Fire up database
mongo.connect("mongodb://localhost:27017/formulas", function(e, db) {
if (e) {return next(e);}
var col = db.collection("users");
//Do a database query to find a record by username
col.findOne({"username": username}, function(err, user){
if (err) { return done(err);}
if(!user) {
return done(null, false, { message: "Please check your log in credentials." });
}
//if it exists call done() object with user information
bcrypt.compare(password, user.password, function(err, res){
if (err) throw err;
if (res == true) {
return done(null, {username: username, password: password});
} else {
return done(null, false, { message: "Invalid password."});
}
});
});
});
}));
I call passport.authenticate() like this:
router.post('/login',
passport.authenticate('local', {successRedirect:'/', failureRedirect:'/about',failureFlash: false}),
function(req, res){
console.log(req.body);
console.log(req.user);
console.log("The user was logged");
});
SerializeUser and deserializeUser look like this:
passport.serializeUser(function(user, done) {
done(null, user.username);
});
passport.deserializeUser(function(id, done) {
mongo.connect("mongodb://localhost:27017/formulas", function(e, db){
if (e) {return next(e);}
var col = db.collection("users");
col.findOne({"username": id}, function(err, user){
done(err, {"username": id});
});
});
});
When I call app.post(/login) I'm taken directly to /about and nothing is logged to the console so I'm not quite sure what's going wrong.
Advice on what to fix or how to troubleshoot is greatly appreciated.
Firstly when u serialize user object , then in deserialize also whole user object must be passed.
Consider the example below.
For routes :
router.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
req.session.user = req.user;
return res.redirect('/home');
});
})(req, res, next);
});
For passport.js , place the localstrategy and passport in same folder
var passport = require('passport'),
session = require('express-session');
var local = require('./localstrategy.js');
module.exports = function (app) {
app.use(session({
secret: 'Site visit',
resave: true,
saveUninitialized: true,
cookie: { secure: false }
}));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done){
done(null, user);
});
passport.deserializeUser(function(user, done){
done(null, user);
});
local();
};
For local strategy :
'use strict';
var passport = require('passport'),
local = require('passport-local').Strategy;
var user;
// path where the db.js is placed
var db = require('./../db.js');
var ObjectId = db.getObjectID();
var bcrypt = require('bcrypt');
module.exports = function(){
passport.use(new local({
usernameField : 'username',
passwordField : 'password'
}, function(username, password, done){
var collection = db.getDb().collection('users');
collection.findOne({
username: username,
}, function (err, result) {
if(result == null){
cb(null, false);
}else {
bcrypt.compare(password, result.password, function (err, passRes) {
if (passRes == true) {
user = user;
done(err, user);
}else{
done(null, false, { message : 'Invalid Password'});
}
});
}
});
}));
};

User Authentication on MEAN stack application

I am building an API using the MEAN stack and am working on the login and signup functions.
And I want to respond with a json string as follows
{
success: 0,
message: ""
}
success:1 for successful login and 0 otherwise.
My authenticate.js is as follows
module.exports = function(passport){
//log in
router.post('/login', passport.authenticate('login', {
//success
//failure
}));
//sign up
router.post('/signup', passport.authenticate('signup', {
//success
//failure
}));
//log out
router.get('/signout', function(req, res) {
req.logout();
res.redirect('/');
});
return router;
}
My passport.init.js middleware is as follows
var mongoose = require('mongoose');
var User = mongoose.model('User');
var LocalStrategy = require('passport-local').Strategy;
var bCrypt = require('bcrypt-nodejs');
module.exports = function(passport){
// Passport needs to be able to serialize and deserialize users to support persistent login sessions
passport.serializeUser(function(user, done) {
console.log('serializing user:',user.username);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
console.log('deserializing user:',user.username);
done(err, user);
});
});
passport.use('login', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
// check in mongo if a user with username exists or not
User.findOne({ 'username' : username },
function(err, user) {
// In case of any error, return using the done method
if (err)
return done(err);
// Username does not exist, log the error and redirect back
if (!user){
console.log('User Not Found with username '+username);
return done(null, false);
}
// User exists but wrong password, log the error
if (!isValidPassword(user, password)){
console.log('Invalid Password');
return done(null, false); // redirect back to login page
}
// User and password both match, return user from done method
// which will be treated like success
return done(null, user);
}
);
}
));
passport.use('signup', new LocalStrategy({
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// find a user in mongo with provided username
User.findOne({ 'username' : username }, function(err, user) {
// In case of any error, return using the done method
if (err){
console.log('Error in SignUp: '+err);
return done(err);
}
// already exists
if (user) {
console.log('User already exists with username: '+username);
return done(null, false);
} else {
// if there is no user, create the user
var newUser = new User();
// set the user's local credentials
newUser.username = username;
newUser.password = createHash(password);
// save the user
newUser.save(function(err) {
if (err){
console.log('Error in Saving user: '+err);
throw err;
}
console.log(newUser.username + ' Registration succesful');
return done(null, newUser);
});
}
});
})
);
var isValidPassword = function(user, password){
return bCrypt.compareSync(password, user.password);
};
// Generates hash using bCrypt
var createHash = function(password){
return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null);
};
};
Please help me out in passing the JSON string accordingly
Using Express, all you have to do is to execute res.json inside any controller, passing it any JavaScript object. Express will automatically convert it to JSON and return it to the user.
return res.json({ success: 0, message: '' }

facebook login error - using MEAN

I am new to MEAN. I've been trying to create a 'facebook' login for my new MEAN Application. I am making use of strategy from: "passport-facebook".
The code from my User.js file, where i've created a new Schema for facebook users is as follows:
var mongoose = require('mongoose');
var fbuserSchema = mongoose.Schema({
id: String,
token: String,
email: String,
name: String
});
var fbUser = mongoose.model('fbUser', fbuserSchema);
My passport.js file has something like this:
var fbUser = mongoose.model('fbUser'),
FacebookStrategy = require('passport-facebook').Strategy;
module.exports = function(){
passport.serializeUser(function (user, done) {
if (user) {
done(null, user.id);
}
});
passport.deserializeUser(function (id, done) {
User.findOne({_id: id }).exec(function (err, user) {
if (user) {
return done(null, user);
} else {
return done(null, false);
}
});
});
passport.use(new FacebookStrategy({
'clientID' : 'xxxxxxxxxxxxxxx',
'clientSecret' : 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'callbackUrl' : 'http://localhost:3030/auth/facebook/callback'
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function(){
fbUser.findOne({'id':profile.id}, function(err, user){
if(err){
return done(err);
}
if(user){
return done(null, user);
}
else{
var newUser = new fbUser();
newUser.id = profile.id;
newUser.token = accessToken;
newUser.name = profile.name.givenName + ' ' + profile.name.familyName;
newUser.email = profiel.emails[0].value;
newUser.save(function(err){
if(err){
throw err;
}
return done(null, newUser);
});
}
});
});
})
)
}
and my routes.js has:
var auth = require('./auth'),
users = require('../controllers/users'),
mongoose = require('mongoose'),
User = mongoose.model('User'),
fbUSer = mongoose.model('fbUser'),
passport = require('passport');
module.exports= function(app) {
app.get('/api/users', auth.requiresRole('admin'), users.getUsers);
app.post('/api/users', users.createUser);
app.put('/api/users', users.updateUser);
app.get('/partials/*', function (req, res) {
res.render('../../public/app/' + req.params[0]);
});
app.post('/login', auth.authenticate);
app.get('/auth/facebook', passport.authenticate('facebook'));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { successRedirect: '/',
failureRedirect: '/login' }));
app.post('/logout', function(req,res){
req.logout();
res.end();
});
app.get('*', function (req, res) {
res.render('index', {
bootstrappedUser: req.user
});
});
}
I have provided the:
a(href="/auth/facebook") Facebook
in my login.jade file.
When i click on this link though all i am getting is a error saying:
The parameter redirect_uri is required
Can someone please help me on this issue.
My facebook URL is as follows:
https://www.facebook.com/v2.2/dialog/oauth?response_type=code&redirect_uri=&client_id=xxxxxxxxxxxxxxxx
I am missing the "redirect_uri=" value in this. How do i get that?
MEAN already had an facebook support;
Go for facebook.js under config/strategies/
Change the facebook id and app secret according to the one you filled in the facebook website.
Thats it

Resources