How can I fix authentication function in passport.js - node.js

I want to make authentication function with Passport.js+Express.
But If I run this code, I receive failure result and null in 'req.user'.
I want to find the problem, but console.log() in localStrategy is not called when I was using passport.authenticate(). I don't know where I have to fix.
How can I fix this code to get proper function?
-app.js
var express = require('express');
var bodyparser=require('body-parser');
var path = require('path');
var cookieParser = require('cookie-parser');
var passport = require('passport'); //passport module add
var localStrategy = require('passport-local').Strategy;
var cookieSession=require('cookie-session');
var index = require('./index.js');
var app=express();
app.use(cookieParser());
app.use(express.static(__dirname+'/views'));
app.use(cookieSession({
keys : ['login'],
cookie : {maxAge:1000*60*60}
}));
app.set('views',__dirname+'/views');
app.set('view engine','html');
app.engine('html',require('ejs').renderFile);
app.use('/',index);
app.listen(8000,function(){
console.log('server started');
});
module.exports=app;
-index.js
var express = require('express');
var router = express.Router();
var bodyparser=require('body-parser');
var crypto=require('crypto');
var passport=require('passport');
var localStrategy=require('passport-local').Strategy;
var mysql=require('mysql');
var config={
host : 'localhost',
port : 3306,
user : 'root',
password : 'xxxxxx',
ssl : true
};
router.use(bodyparser.json());
router.use(passport.initialize());
router.use(passport.session());
const conn = new mysql.createConnection(config);
conn.connect(function(err){
if(err){
console.log('Cannot Connect to database : ');
throw err;
}
else{
console.log('Success to connect database');
}
});
passport.use(new localStrategy({
usernameField : 'username',
passwordField : 'password',
},function(req,username,password,done){
conn.query('USE Database');
conn.query('select userID as username, userPWD as password from UserTable where userID=?',[username],function(err,userinfo,fields){
if(err){
return done(err);
}
else{
if(username==userinfo[0].username){
var encryptHash=crypto.createHash('sha512').update(password);
if(encryptHash===password){
return done(null,userinfo[0]);
}
console.log('login succeed');
return done(null,userinfo[0]);
}
else{
return done(null,false);
}
}
});
})
);
passport.serializeUser((user,done)=>{
console.log("hello2");
done(null, user.username);
});
passport.deserializeUser((id,done)=>{
console.log("hello");
var sql='select userID as username, userPWD as password from UserTable where userID=?';
conn.query(sql,[id],(err,userinfo,fields)=>{
if(err){
console.log("error 발생 : "+err);
res.status(500).send("Internal Server Error");
}
else{
if(userinfo[0].username==id){
done(null,userinfo[0]);
}
}
});
});
router.get('/',function(req,res,next){
console.log('homepage');
res.render('index');
});
router.post('/login',passport.authenticate('local',{failureRedirect:'/',successRedirect:'/main'}));
module.exports=router;

You should check the "req" param inside
function(req,username,password,done)
may be this function takes only three parameters
**http://www.passportjs.org/packages/passport-local/**
you should check what you get on post request through this `req` using this function

Related

Authentication form with passport long load time and fails without message

I'm using passport with nodejs, express and EJS. I've created a authentication form but when I want to submit the server never responds and then resets the connection without any error message.
Here my server.js
var express = require("express");
var MongoClient = require("mongodb");
var bodyParser = require('body-parser')
var cons = require('consolidate');
var octicons = require("octicons");
var app = express();
var url = process.env.URL || "mongodb://localhost:27017/";
var dbName = process.env.DBNAME || "blog";
var port = process.env.PORT || 8000;
var routes = require("./routes");
var session = require('express-session')
var compte = require('./models/compte');
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
require('./config/passport')(passport);
app.engine('html', cons.pug);
app.set('view engine', 'html');
app.set('views', __dirname + '/views')
app.use(express.static(__dirname + '/assets'));
app.use(morgan('dev'));
app.use(cookieParser());
app.use(bodyParser());
app.use(session({ secret: 'simonahalepnumberone' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
MongoClient.connect(url, function(err, client) {
if(err) throw err;
routes(app, passport);
app.client = client;
app.db = client.db(dbName);
app.listen(port, function() {
console.log("now listening on http://localhost:" + port)
});
});
module.exports = app;
My index.js (which contains routes)
var posts = require("./posts");
module.exports = function(app, passport) {
function convertDate(dateString) {
var date = new Date(dateString);
return date.getDate()+"/"+date.getMonth()+"/"+date.getFullYear();
}
app.get("/", function(req, res) {
app.db.collection("articles").find({}).sort({date: 1}).toArray(function(err, result){
if(err) throw err;
result = result.reverse();
for(i = 0; i < result.length; ++i){
result[i].article = result[i].article.substr(0,75);
result[i].date = convertDate(result[i].date);
}
res.render("pages/index.ejs", {"articles": result})
});
});
app.get('/connexion', function (req, res, next) {
res.render("pages/connexion.ejs", { message: req.flash('connexionMessage') });
});
app.post('/connexion', passport.authenticate('local-login', {
successRedirect : '/',
failureRedirect : '/connexion',
failureFlash : true
}));
app.get('/deconnexion', function(req, res) {
req.logout();
res.redirect('/');
});
app.get('*', function(req, res){
res.render("pages/erreur404.ejs");
});
// Register posts endpoint
posts(app);
}
My passport.js
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/compte');
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-login', new LocalStrategy({
usernameField : 'pseudo',
passwordField : 'password',
passReqToCallback : true
},
function(req, pseudo, password, done) {
User.findOne({ 'local.pseudo' : pseudo }, function(err, user) {
if (err)
return done(err);
if (!user)
return done(null, false, req.flash('connexionMessage', 'Erreur dans le pseudo.'));
if (!user.validPassword(password))
return done(null, false, req.flash('connexionMessage', 'Erreur dans le mot de passe'));
return done(null, user);
});
}));
};
And my model for the user account
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var compteSchema = mongoose.Schema({
local : {
pseudo : String,
password : String,
}
});
compteSchema.methods.genererHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
compteSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
module.exports = mongoose.model('utilisateur', compteSchema);
I've follow this tutorial so I don't understand why it's not working
link

Issue with passport module in Node js

i am trying to use passport in my Node js Login system which is working with mongodb.
I have included both passport module and Local strategy in my app.js file.
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var expressValidator=require('express-validator');
var cookieParser = require('cookie-parser');
var session= require("express-session");
var passport=require("passport");
var LocalStrategy=require('passport-local').Strategy;
var bodyParser = require('body-parser');
var multer=require("multer");
var flash=require('connect-flash');
var mongo=require('mongodb');
var mongoose=require('mongoose');
var db=mongoose.connection;
In users route file i have declared users
var express = require('express');
var router = express.Router();
var passport=require("passport");
var LocalStrategy=require('passport-local').Strategy;
var User=require('../models/users');
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.get('/register', function(req, res, next) {
res.render('register',{
"title":'Register'
});
});
router.get('/login', function(req, res, next) {
res.render('login',{
"title":'Login'
});
});
router.post('/register', function(req, res, next){
//get the form values
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;
//Check for image filed
if(req.files&&req.files.profileimage){
console.log('Uploading file....');
//File Info
var profileimageoriginalname =req.files.profileimage.originalname;
var profileimagename=req.files.profileimage.name;
var profileimageMime=req.files.profileimage.mimetype;
var profileimagePath=req.files.profileimage.path;
var profileimageExt=req.files.profileimage.extension;
var profileimageSize=req.files.profileimage.size;
}else{
//Set a default image
var profileimageName="noimage.png";
}
//Form Validation
req.checkBody('name',"nAME FILED IS REquiered").notEmpty();
req.checkBody('email',"email FILED IS REquiered").isEmail();
req.checkBody('username',"UsernamenAME FILED IS REquiered").notEmpty();
req.checkBody('password',"password FILED IS REquiered").notEmpty();
req.checkBody('password2',"password font marchjFILED IS REquiered").equals(req.body.password);
//Check for errors
var errors = req.validationErrors();
if(errors){
res.render('register',{
errors:errors,
name:name,
email:email,
username:username,
password:password,
password2:password2
});
}else{
var newUser=new User({
name:name,
email:email,
username:username,
password:password,
profileimage:profileimagename
});
//Create user
User.createUser(newUser,function(err,user){
if(err)throw err;
console.log(user);
});
//Sucess message
req.flash('success',"You are now registered and may login");
res.location('/');
res.redirect('/');
}
});
passport.serializeUser(function(user,done){
done(null,user.id);
});
passport.deserializeUser(function(id,done){
User.getUserbyId(id,function(err,user){
done(err,user);
});
});
passport.use(new LocalStrategy(
function(username,password,done){
User.getUserByUsername(username,function(err,user){
if(err) throw err;
if(!user){
console.log("Unknown user");
return done(null,false,{message:"unknown user"});
}
User.comparePassword(password,user.password,function(err,isMatch){
if(err) throw err;
if(isMatch){
return done(null,user);
}else{
console.log("invalid password");
return done(null,false,{message:"invalid passwors"});
}
});
});
}
));
router.post('/login',passport.authenticate('local',{failureRedirect:"/users/login/",failureFlash:"Wrong login or pass"}),function(req,res){
console.log("Authentication Successfully done");
req.flash('success',"You are loged in");
res.redirect('/');
});
module.exports = router;
And also i have created a module for my users login
var mongoose=require('mongoose');
var bcrypt=require('bcrypt');
mongoose.connect('mongodb://localhost/nodeAuth', { useMongoClient: true });
var db=mongoose.connection;
//User scheme
var UserSchema=mongoose.Schema({
usernam:{
type:String,
index:true
},
password:{
type:String,required:true,bcrypt:true
},
email:{
type:String
},
name:{
type:String
},
profileimage:{
type:String
}
});
var User=module.exports=mongoose.model('User',UserSchema);
module.exports.comparePassword=function(candidatePassword,hash,callback){
bcrypt.compare(candidatePassword,hash,function(err,isMatch){
if(err) return callback(err);
callback(null,isMatch);
});
}
module.exports.getUserById=function(id,callback){
User.findById(id,callback);
}
module.exports.getUserByUsername=function(username,callback){
var query={username:username};
User.findOne(query,callback);
}
module.exports.createUser=function(newUser,callback){
bcrypt.hash(newUser.password, 10,function(err,hash){
if(err)throw err;
//Set hashed password
newUser.password=hash;
//create User
newUser.save(callback)
});
}
But its'nt returning aboslutely nothing.
COuld anyone help?
I think it's mostly connected with passport module,but also i have absolutely nor errrors which i can debug.
I mongodb it's showing the whole of my databases.I am trying to log in with my login which is previously registered in my database and works fine but its'nt returning nothing.It's just refrashing the page.
Check out your schema:
//User scheme
var UserSchema=mongoose.Schema({
usernam:{
type:String,
index:true
},
...
It should be "usernamE" :)

How to make API call using API token in Node.js using express, passport-local

I'm a newbie in Node.js and trying to use API token to access Grafana.
And I created one API token by following instruction from Grafana page.
However, I don't know how to make API calls from my code of node.js to access my local server of grafana page. Also, I have a local login-page by using mongoDB to manage users.
How can I make Node.js API calls to access my local server of grafana page?
Please help me out here.. I'm having hard time on this..
If you want me to show code, I can edit here..
EDIT:
This is my whole code for app.js
var io = require('socket.io');
var express = require('express');
var app = express();
var redis = require('redis');
var sys = require('util');
var fs = require('fs');
//Added for connecting login session
var http = require('http');
var server = http.createServer(app);
var path = require('path');
var mongoose = require('mongoose');
var passport = require('passport');
var session = require('express-session');
var flash = require('connect-flash');
var async = require('async');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
//Adding grafana
var request = require('request');
//Connecting Database (MongoDB)
mongoose.connect("my mongoDB private address");
var db = mongoose.connection;
db.once("open",function () {
console.log("DB connected!");
});
db.on("error",function (err) {
console.log("DB ERROR :", err);
});
//Setting bcrypt for password.
var bcrypt = require("bcrypt-nodejs");
//Setting userSchema for MongoDB.
var userSchema = mongoose.Schema({
email: {type:String, required:true, unique:true},
password: {type:String, required:true},
createdAt: {type:Date, default:Date.now}
});
userSchema.pre("save", function (next){
var user = this;
if(!user.isModified("password")){
return next();
} else {
user.password = bcrypt.hashSync(user.password);
return next();
}
});
//setting bcrypt for password.
userSchema.methods.authenticate = function (password) {
var user = this;
return bcrypt.compareSync(password,user.password);
};
//Setting User as userSchema.
var User = mongoose.model('user',userSchema);
io = io.listen(server);
//Setting middleware for login format.
app.set("view engine", 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.use(flash());
app.use(session({secret:'MySecret', resave: true, saveUninitialized: true}));
app.use(passport.initialize());
app.use(passport.session());
//Initializing passport.
passport.serializeUser(function(user, done) {
//console.log('serializeUser()', user);
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
//console.log('deserializeUser()', user);
User.findById(id, function(err, user) {
done(err, user);
});
});
var username_tmp = '';
var global_username = ''; //Global variable for username to put in the address
var pass = '';
//Initializing passport-local strategy.
var LocalStrategy = require('passport-local').Strategy;
passport.use('local-login',
new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
User.findOne({ 'email' : email }, function(err, user) {
if (err) return done(err);
if (!user){
req.flash("email", req.body.email);
return done(null, false, req.flash('loginError', 'No user found.'));
}
if (!user.authenticate(password)){
req.flash("email", req.body.email);
return done(null, false, req.flash('loginError', 'Password does not Match.'));
}
var email_address = req.body.email;
username_tmp = email_address;
var username = email_address.substring(0, email_address.lastIndexOf("#"));
global_username = username;
pass = req.body.password;
return done(null, user);
});
}
)
);
//Check whether it is logged in or not.
//If it is not logged in(Session is out), it goes to login page
//If it is logged in(Session is still on), it goes directly to status.html
app.get('/', loggedInCheck);
app.get('/login', function (req, res) {
res.render('login/login',{email:req.flash("email")[0], loginError:req.flash('loginError')});
});
//Accessing to MongoDB to check to login or not
app.post('/login',
function (req,res,next){
next();
}, passport.authenticate('local-login', {
successRedirect : '/status',
failureRedirect : '/login',
failureFlash : true
})
);
//Creating new account
app.get('/users/new', function(req,res){
res.render('users/new', {
formData: req.flash('formData')[0],
emailError: req.flash('emailError')[0],
passwordError: req.flash('passwordError')[0]
}
);
});
//Calling status.html
app.get('/status', isLoggedIn, function(req, res){
var user_temp = {user: ''};
user_temp.user = global_username;
res.render('status/status', user_temp);
//res.redirect('/status.html?channel=' + global_username);
});
app.get('/grafana', isLoggedIn, function(req, res){
console.log('Accessing to grafana');
res.redirect('http://localhost:8080');
});
request.get('http://localhost:8080',{
auth: {
bearer: 'TOKEN HERE'
}
});
server.listen(4000);
Edited more
app.get('/grafana', isLoggedIn, function(req, res){
console.log('Accessing to grafana');
var url = 'http://localhost:8080/api/dashboards/db/test';
request.get(url,{
auth: {
bearer: 'API token from Grafana page'
}
});
res.redirect(url);
});
Thank you..
The API calls are made with HTTP requests. You can use the request package from npm.
From the docs:
You use the token in all requests in the Authorization header, like this:
GET http://your.grafana.com/api/dashboards/db/mydash HTTP/1.1
Accept: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
Example (I'm using request-promise but you can use whatever you want):
let request = require('request-promise');
let url = `http://your.grafana.com/api/dashboards/db/mydash`;
//Obviously replace this with your token
let myToken = `eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk`;
request.get(url).auth(null, null, true, myToken).then(res=> { ... });
// or
request.get(url, {
auth: {
bearer: myToken
}
}).then(res=> { ... });

Node/express app skips user authentication middleware and goes straight to callback

I have a middleware isAuthenticated to ensure that the user is logged in before he can post a comment:
function isAuthenticated(req,res,next) {
req.isAuthenticated ? next() : res.redirect('/login');
}
This middleware is suppose to be running here:
router.post('/cat/:id', isAuthenticated, function(req,res) {
console.log('not suppose to be here');
var id = req.params.id;
Cat.findById(id, function(err, cat) {
if (err) {
console.log(err);
} else {
var id = req.params.id;
var comment = new Comment({
username: req.user.username,
content: req.body.content
});
//more code
However, when I try to post a comment without logging in, my app crashes and the console shows the following:
not suppose to be here
username: req.user.username,
^
TypeError: Cannot read property 'username' of undefined
I refactored all the routes into a separate file, and exported it to app.js. All routes pertaining to cats are stored in cats.js:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var Cat = require('../models/cat.js');
var Comment = require('../models/comment.js');
var mongoose = require('mongoose');
router.use(function(req,res,next) {
res.locals.user = req.user;
next();
});
function isAuthenticated(req,res,next) {
req.isAuthenticated ? next() : res.redirect('/login');
}
router.get('/cat/:id', function(req,res) {
var id = req.params.id;
Cat.findById(id, function(err, cat) {
if (err) {
console.log(err);
} else {
Comment.find({}, function(err, comments) {
if (err) {
console.log(err);
} else {
res.render('show', {cat:cat, comments:comments});
}
});
}
});
});
//more code
module.exports = router;
app.js:
var app = express();
var bodyParser = require('body-parser');
var config = require('./config/config.js');
var mongoose = require('mongoose');
var Cat = require('./models/cat.js');
var Comment = require('./models/comment.js');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local');
var passportLocalMongoose = require('passport-local-mongoose');
var User = require('./models/user.js');
mongoose.connect(config.dbURL, function(err) {
if (err) {
console.log(err);
} else {
console.log('successfully connected to database!');
}
});
app.set('view engine', 'ejs');
app.use(session({
secret:"sfsdfsdfsd",
resave: false,
saveUninitialized: false
}));
app.use(bodyParser.urlencoded({extended:true}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.engine('html', require('ejs').renderFile);
app.use(express.static('public'));
var authRoutes = require('./routes/auth.js');
var catRoutes = require('./routes/cats.js');
app.use(authRoutes);
app.use(catRoutes);
Why is my middleware being bypassed? Please ask for additional code if it's needed.
Edit1: Updated to provide more information.
I solved the problem. I just forgot to call req.isAuthenticated in my middleware. I had it as:
function isAuthenticated(req,res,next) {
req.isAuthenticated ? next() : res.redirect('/login');
}
Whereas it should have been req.isAuthenticated().

passportjs validate on signup if user already exists

I am trying to create a sign up where the user if already existing in the db is logged into the system, or else a new user is created in the system.
So far I have come up with the following code.
//filename passport-config
var config = require('./config');
var passport = require('passport');
var User = require('./models/user');
var LocalStrategy = require('passport-local').Strategy;
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);
}
// As with any middleware it is quintessential to call next()
// if the user is authenticated
var isAuthenticated = function (req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
passport.use('signup', new LocalStrategy({
passReqToCallback : true
},
function(req, email, password, done) {
findOrCreateUser = function(){
// find a user in Mongo with provided email
User.findOne({'email':email},function(err, user) {
// In case of any error return
if (err){
console.log('Error in SignUp: '+err);
return done(err);
}
// already exists
if (user) {
User.findOne({ 'email' : email },
function(err, user) {
if (!user){
console.log('User Not Found with email '+email);
return done(null, false);
}
// User exists but wrong password, log the error
if (!isValidPassword(user, password)){
console.log('Invalid Password');
return done(null,false);
}
});
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.email = email;
newUser.password = createHash(password);
// save the user
newUser.save(function(err) {
if (err){
console.log('Error in Saving user: '+err);
throw err;
}
console.log('User Registration succesful');
return done(null, newUser);
});
}
});
};
// Delay the execution of findOrCreateUser and execute
// the method in the next tick of the event loop
process.nextTick(findOrCreateUser);
})
);
my router
router.post('/signup', passport.authenticate('signup', {
successRedirect: '/timeslot',
failureRedirect: '/'
}));
my server.js file
var express = require('express');
var bodyParser = require('body-parser');
var leisure = require('leisure');
var cors = require('cors');
var passport = require('passport');
var config = require('./config');
var passportConfig = require('./passport-config');
var session = require('express-session')
var expressHbs = require('express-handlebars');
var mediaTypes = [
{ contentType: 'application/hal+json' },
{ contentType: 'application/json' },
{ contentType: 'text/html' }
];
var app = express();
/*Handlebars */
app.engine('handlebars', expressHbs({layout: false}) );
app.set('view engine', 'handlebars');
app.use(express.static(__dirname + '/assets'));
app.use(cors(config.settings.cors));
app.use(bodyParser());
app.use(leisure.accept(mediaTypes));
/*sessions */
app.use(session({
secret: 'keyboardSFS23432##!#!#at'
}));
app.use(passport.initialize());
app.use(passport.session());
var routes = require('./routes');
app.use('/', routes.router);
function start () {
var port = process.env.PORT || 3000;
app.listen(port);
console.log('Appoints service started on port ' + port);
}
exports.app = app;
exports.start = start;
The signup route doesn't work at all and I am pretty confused on how to debug this, any suggestions will be appreciated.
Have a look at the excellent article at
http://scotch.io/tutorials/javascript/easy-node-authentication-setup-and-local
and the sample code at
https://github.com/scotch-io/easy-node-authentication (with MongoDB), or
https://github.com/tobilg/easy-node-authentication-redis (with Redis as backend)

Resources