I was trying to learn how to use passport-local with its documentation and I could do this, however when I submit the form it does not redirect to any site
const express = require("express");
const router = express.Router();
const passport = require("passport");
const localStrategy = require("passport-local").Strategy;
const UserList = [{ email: "1#1", password: "1" }];
passport.use(new localStrategy(async (email, password, done) => {
const thisUser = UserList.find(x => x.email = "email" && x.password == password);
return done(null, thisUser)
}));
router.get('/signup', (req, res) => {
res.render('auth/signup.hbs')
});
router.post('/signup', (req, res) => {
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login'
})
});
module.exports = router;
You forgot to initialize passport with
app.use(passport.initialize());
and serializeUser with
passport.serializeUser(function (user, done) {
done(null, user);
});
You can view the full example below. I did a test and it worked.
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var passport = require('passport');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var LocalStrategy = require('passport-local').Strategy;
app.use(morgan('dev')); // log tất cả request ra console log
app.use(cookieParser()); // đọc cookie (cần cho xác thực)
app.use(bodyParser()); // lấy thông tin từ html forms
app.set('view engine', 'ejs'); // cài đặt ejs là templating
app.use(passport.initialize());
const UserList = [{email: "1#1", password: "1"}];
passport.serializeUser(function (user, done) {
done(null, user);
});
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // cho phép chúng ta gửi reqest lại hàm callback
},
function (req, email, password, done) {
process.nextTick(function () {
const thisUser = UserList.find(x => x.email = "email" && x.password == password);
return done(null, thisUser)
});
}));
//
// routes ======================================================================
app.get('/', function (req, res) {
res.render('index.ejs'); // load the index.ejs file
});
app.get('/signup', function (req, res) {
res.render('signup.ejs');
});
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/',
failureRedirect: '/signup',
}))
// launch ======================================================================
app.listen(port);
console.log('The magic happens on port ' + port);
Related
I have been trying to build the authentication using PassportJs and MongoDB. I am using PassportJS only to log in. But, while submitting the post request it does not redirect me to the failureRedirect route, nor to the SuccessRedirect one, instead, the web page enters into an endless loop.
The code I have written is -
It has 2 files- app.js and user.js
App.js file -
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const passport = require('passport');
const mongoose = require('mongoose');
require('./db/db')
var fileupload = require('express-fileupload');
const path = require('path');
const app = express();
app.use(fileupload({
useTempFiles: true
}));
const session = require('express-session');
const mongostore = require('connect-mongo');
app.use(express.static(path.join(__dirname,'public')));
// session middle ware
app.use(session({
secret : 'mysupersecret',
resave : false,
saveUninitialized : false,
store: mongostore.create({
mongoUrl: process.env.DB,
}),
cookie : { maxAge : 180 * 60 * 1000 }
}));
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static("public"));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(passport.session());
app.get("/", (req, res) => {
res.render("index");
});
app.use("/admin", require("./routes/admin"));
app.use("/user", require("./routes/user"));
app.use("/task", require("./routes/task"));
// PORT
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`Server started on port ${PORT}`));
User.js file -
const express = require("express");
const bodyParser = require("body-parser");
const router = express.Router();
const bcrypt = require("bcryptjs");
const passport = require("passport");
const User = require("../models/User");
const Task = require("../models/Task");
var LocalStrategy = require('passport-local');
// var bcrypt = require('bcryptjs');
var strategy = new LocalStrategy(function verify(email, password, done) {
try{
console.log(email);
User.findOne({email: email}, function (err, user) {
console.log(email);
if (err)
console.log(err);
if (!user) {
console.log("doen exist")
return done(null, false);
}
bcrypt.compare(password, user.password, function (err, isMatch) {
if (err)
console.log(err);
if (isMatch) {
return done(null, user);
} else {
console.log("galat password");
return done(null, false);
}
});
});
}catch(err){
console.log(err);
}
});
passport.use('epass',strategy);
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
// User login
router.get("/login", (req, res) => {
res.render("user-login");
});
router.post("/login", (req,res) => {
try{
passport.authenticate('epass', { failureRedirect: '/user/login' }),
function(req, res,next) {
res.redirect('/user');
}
}catch(err){
console.log(err);
}
});
router.get("/", (req, res) => {
res.render("user")
})
module.exports = router;
I have searched everywhere and tried all the available possible solutions but nothing is solving this.
passport.authenticate() should be used as a middleware, not as a regular function:
router.post("/login",
passport.authenticate('epass', { failureRedirect: '/user/login' }),
function(req, res,next) {
res.redirect('/user');
}
);
The way you were using it causes the request to POST /user/login to never finish, because it's not sending back any response.
EDIT: also, make sure that you either use the default field names of username and password for logging in, or add the relevant options to the constructor of LocalStrategy to tell it which fields it should be expecting.
I am using node.js express with sequelize and database postgreSql.the problem is in passport login failureRedirect works properly sucessRedirect does not redirect to the page that I want. It still loading and not responding anything and does not come any error.
when I submit login it will check for errors if errors it will work perfectly in failureRedirect but in Success it does not work like page has loading only not goes to the destination page and if I stop the project and restart the project it will be in destination page!! i dont know what is the problem help me.
mainController.js
const express = require("express");
const sessions = require("express-session");
require("../model/MasterUser.model");
const passport = require("passport");
var session = sessions;
const router = express.Router();
router.get("/dashboard", (req, res) => {
res.render('dashboard');
});
router.get("/login", (req, res) => {
res.render("login", { layout: "login.hbs" });
});
router.post(
"/login",
passport.authenticate("local", {
successRedirect: "/main/dashboard",
failureRedirect: "/main/login",
failureFlash: true,
})
);
module.exports = router;
passport.js
const LocalStrategy = require("passport-local").Strategy;
const bcrypt = require("bcryptjs");
const sequelize = require("sequelize");
const masterUser = require("../model/MasterUser.model");
module.exports = function (passport) {
passport.use(
new LocalStrategy(
{ usernameField: "user_name" },
(user_name, password, done) => {
// Match user
masterUser.findOne({ where: { user_name: user_name } }).then((user) => {
if (!user) {
return done(null, false, {
message: "This username is not registered",
});
}
// Match password
bcrypt.compare(password, user.password, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
return done(null, user);
} else {
return done(null, false, { message: "Password incorrect" });
}
});
});
}
)
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
masterUser.findByPk(id, (err, user) => {
done(err, user);
});
});
};
index.js
const express = require("express");
const Handlebars = require("handlebars");
var flash = require("connect-flash");
const app = express();
const path = require("path");
const bodyparser = require("body-parser");
const expressHandlebars = require("express-handlebars");
const passport = require("passport");
const sessions = require("express-session");
var session = sessions;
const MainController = require("./controllers/MainController");
const db = require("./config/database");
//test db
db.authenticate()
.then(() => console.log("Database Connected..."))
.catch((err) => console.log("error" + err));
//for security purpose
const cors = require("cors");
app.use(
cors()
);
//Passport Config
require("./config/passport")(passport);
app.use(cookieParser());
//use body parser
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({ extended: true }));
const {
allowInsecurePrototypeAccess,
} = require("#handlebars/allow-prototype-access");
app.use(
bodyparser.urlencoded({
urlencoded: true,
})
);
app.use(
sessions({
secret: "secret_key",
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60000 },
})
);
// use flash for show messages
app.use(flash());
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
//flash messages
app.use((req, res, next) => {
res.locals.success_msg = req.flash("success_msg");
res.locals.error_msg = req.flash("error_msg");
res.locals.error = req.flash("error");
next();
});
//setting up view Engine
app.set("views", path.join(__dirname, "/views"));
//using the hbs
app.engine(
"hbs",
expressHandlebars({
extname: "hbs",
defaultLayout: "default",
layoutsDir: __dirname + "/views/layouts",
handlebars: allowInsecurePrototypeAccess(Handlebars),
})
);
app.set("view engine", "hbs");
//route for Main
app.use("/main", MainController);
//default
app.get("/", (req, res) => {
res.render("login");
});
app.listen(3000, () => {
console.log("App listening on port 3000!");
});
the problem has been solved guys I made done wrong code in deserializeUser.
passport.js before
passport.deserializeUser((id, done) => {
masterUser.findByPk(id, (err, user) => {
done(err, user);
});
});
};
passport.js after
passport.deserializeUser(function (id, done) {
masterUser.findOne({ where: { id: id } }).then((user) => {
done(null, user);
});
});
the problem is for sequelize get the user data is different so now its worked for me.this is useful for who using express with sequelize and passport with postgresql
I am trying to create a tweet to the user profile using twit package. This is the code I am using. By using this code I am able to tweet to my profile because I have access_token and access_token_secret. My question is If I want to tweet to some other people's profile. What is the procedure to do it I am not able to understand? I am using passport library to get the user details.
var Twit = require('twit');
var T = new Twit({
consumer_key: '************',
consumer_secret: '**********',
access_token: '******************',
access_token_secret: '******************',
timeout_ms: 60 * 1000,
strictSSL: true,
})
T.post('statuses/update', {status: 'hello world! '}, function(err, data, response) {
console.log('post on ',data);
})
Below down is my passport authentication code
'use strict';
require('dotenv').config();
const path = require('path');
const express = require('express');
const passport = require('passport');
const { Strategy } = require('passport-twitter');
const { TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, SESSION_SECRET } = process.env;
const port = process.env.PORT || 3000;
const app = express();
const routes = require('./routes');
passport.use(new Strategy({
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callbackURL: '/return'
},
(token, tokenSecret, profile, cb) => {
console.log(token);
console.log(tokenSecret);
console.log(profile);
return cb(null, profile);
}));
passport.serializeUser((user, cb) => {
cb(null, user);
});
passport.deserializeUser((obj, cb) => {
cb(null, obj);
});
app.set('view engine', 'ejs');
app.use('/public', express.static(path.join(__dirname, 'public')));
app.use(require('express-session')({ secret: SESSION_SECRET, resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use('/', routes);
app.listen(port);
another file
'use strict';
const express = require('express');
const passport = require('passport');
const router = express.Router();
router.get('/', (req, res, next) => {
const { user } = req;
console.log('user details', req.user);
// res.render('home', { user });
});
router.get('/login/twitter', passport.authenticate('twitter'));
router.get('/logout', (req, res, next) => {
req.logout();
res.redirect('/');
});
router.get('/return',
passport.authenticate('twitter', { failureRedirect: '/' }),
(req, res, next) => {
res.redirect('/');
});
module.exports = router;
Got the answer following these steps. https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a
my app.js is
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
app.set('views', __dirname+'/views');
app.set('view engine', 'ejs');
app.use(bodyParser());
app.use(cookieParser());
app.use(session({secret : 'somthing'}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next){
res.locals.message = req.flash();
console.log(res.locals);
next();
});
app.use(require('./controller/router'));
// Default Controller Come Here
app.listen(3000, function(){
console.log('Running');
})
router.js is
var express = require('express');
var router = express.Router();
router.use('/', require('./home'));
router.use('/login', require('./login'));
router.use('/user', require('./user'));
module.exports=router;
passport.js (inside of config folder)
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../model/users');
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
done(err, id);
});
passport.use(new LocalStrategy(function(username, password, done){
if(username == "test#test.com")
/* hardcore check username and password */
{
if(password=="123")
{
var result = { id : 1, fullname : "james", username : "jamesjoel"};
console.log("Success");
return done(result, true);
}
return done(null, false, { message : "Incorrect Passwordtttt"});
}
return done(null, false, { message : "Incorrect Username and password"});
}
));
module.exports=passport;
and finaly my login.js controller is
var passport = require('../config/passport');
var express = require('express');
var router = express.Router();
router.post('/', passport.authenticate('local', {
successRedirect: '/user',
failureRedirect: '/login',
failureFlash: true
})
);
router.get('/', function(req, res){
console.log(req.flash());
res.render('login', { msg : req.flash()});
});
module.exports=router;
but when i send correct username and password it show in console "success" and show [Object Object] and successRedirect not working infact i wrote somthing on .serializeUser() and .deserializeUser() its also not showing on console....
so please help me for this .....
done is a callback and it takes first argument as an error. But in your case after success still you are passing value as error try to make it null like this return done(null,result, true)
if(password=="123"){
var result = { id : 1, fullname : "james", username : "jamesjoel"};
console.log("Success");
return done(null,result, true);
}
I'm trying to run some basic tests with passport on Node, and when I try to access the route localhost:3000/login I get a Bad request 400. Here is the code:
var express = require('express');
var app = express();
var jwt = require('jsonwebtoken');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
var user = {
username: "name",
password: "password123"
}
return done(null, user);
}
));
app.post('/login',
passport.authenticate('local', {session: false}),
function(req, res) {
req.user.name = "Giuan";
res.send(req.user.name);
//res.redirect('/users/' + req.user.username);
});
app.listen(3000, ()=>{
console.log('Running on port 3000');
})
Try this:
var express = require('express');
var app = express();
var jwt = require('jsonwebtoken');
var passport = require('passport');
var bodyParser = require('body-parser');
//if you are getting the info (username and password) through the body
//of the http request you need to use body-parser
app.use(bodyParser());
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
var user = {
username: "name",
password: "password123"
}
return done(null, user);
}
));
app.use(passport.initialize());
app.post('/login',
passport.authenticate('local', {session: false}),
function(req, res) {
req.user.name = "Giuan";
res.send(req.user.name);
//res.redirect('/users/' + req.user.username);
});
app.listen(3000, ()=>{
console.log('Running on port 3000');
})
Use app.use(passport.initialize()); you haven't initialize passport in your code.
var express = require('express');
var app = express();
var jwt = require('jsonwebtoken');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
var user = {
username: "name",
password: "password123"
}
return done(null, user);
}
));
app.use(passport.initialize());
app.post('/login',
passport.authenticate('local', {session: false}),
function(req, res) {
req.user.name = "Giuan";
res.send(req.user.name);
//res.redirect('/users/' + req.user.username);
});
app.listen(3000, ()=>{
console.log('Running on port 3000');
})
I was also facing the same issue and just fixed it by adding usernameField and passwordField keys to the localStrategy options.
new localStrategy({
usernameField: 'email',
passwordField: 'password'
}, function (email, password, done) {
// Do something here
});