how to place passport js configuration in a common file - javascript

I am using Passport js for authentication in my project. At server side i am using Express js. In app.js i have configuration for passport js and the code is:
passport.use(new Strategy({
passReqToCallback: true
},
function (req, username, password, done) {
req.models.users.find({ 'user_id' : username }, function (err, user) {
if (err) { return done(err); }
if (!user[0]) {
console.log("The username is Incorrect");
return done(null, false, { message: 'Incorrect username.' });
}
if (user[0].default_password!=password) {
console.log("The Password is Incorrect");
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
and after this i am verifying the client request like this:
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
Till here everything is working fine.
Now i want to place this route app.post('/login',... in routes folder so i have given the path of the route in app.js like this:
var users = require('./routes/users/users');
app.use('/users', users);
My problem is: in this user route file i don't have passport configuration and i don't want to rewrite it again for all my other routes so i am thinking to place the passport configuration in a common file and reuse it but i don't know how to do it. If you have any idea please help. Thanks.

You can write a middleware, lets call it auth.js, that checks for session info and mount this for every route that you need.
'use strict';
const qs = require('querystring'),
router = require('express').Router();
router.use(function (req, res, next) {
// set this in res.locals
if (!req.user) {
return res.redirect('/?' + qs.stringify({
'r': req.originalUrl
}));
}
next();
});
module.exports = router;
If you use the above approach, you will need to add res.locals.user = req.user; in your server/app.js.
After this, you can require the above middleware on every route that needs to be authenticated.
router.verb('/path', require('./path-to-auth'));
router.verb('/path', (req, res, next) => {
// this route will only be executed if the user is authenticated
});

Related

NodeJS - Passport local strategy gives me 404

I have a tremendous headche with a problem when I try to login using Passport.
I'm making a post request to /login with an email and password. Passport authenticates it correctly, err isn't called and then return res.redirect('/user') gets called too but it returns 404 and doesn't redirect.
I don't know why this is happening. Here's my code:
Server (index.js):
const
express = require('express'),
app = express(),
mongoose = require('mongoose'),
passport = require('passport'),
cookieSession = require('cookie-session'),
bodyParser = require('body-parser'),
keys = require('./config/keys'),
user = require('./models/User'),
passportService = require('./services/passport'),
authRoutes = require('./routes/auth');
mongoose.connect(keys.mongoURI);
app.use(bodyParser.json());
app.use(
cookieSession({
maxAge: 15 * 24 * 60 * 60 * 1000,
keys: [keys.cookieKey]
})
);
app.use(passport.initialize());
app.use(passport.session());
passportService(passport);
authRoutes(app);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
});
passportService (passport.js):
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
const User = mongoose.model('users');
module.exports = (passport) => {
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser((id, done) => {
User.findById(id).then(user => {
done(null, user);
});
});
passport.use(
new LocalStrategy(
{
usernameField: 'emailaddr',
passwordField: 'passwd'
},
function(username, password, done) {
User.findOne({ email: username }, function(err, user) {
if(err){
return done(err);
}
if(!user) {
console.log('User not found with email: ', username);
return done(null, false);
}
if(user.password != password) {
console.log('Invalid password');
return done(null, false)
}
return done(null, user);
});
}));
}
Authentication route:
const passport = require('passport');
module.exports = app => {
app.post('/api/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); }
return res.redirect('/user');
});
})(req, res, next);
});
}
There is not route for /user because I'm working with React and React Router in the client.
Please I need your help!!!
I would suggest not using the custom callback on your authenticate function. Instead, check to see if after the api is called and authentication is run if you have a user attached to the request object.
// calling redirects from your api will be problematic with react router
// allow your front end to decide what route to call based on the response
app.post('/api/login', passport.authenticate('local'), function(req, res, next) {
if(req.user) {
res.json(req.user);
} else {
// handle errors here, decide what you want to send back to your front end
// so that it knows the user wasn't found
res.statusCode = 503;
res.send({message: 'Not Found'})
}
});

Implement passportjs and angular4

Look, i've made a mean stack app with register/login using passportjs, and it was fine, when i change to angular2(the other was on angularjs) i've made the backend side and i think it works but i dont know how to test it on the fronted side, i know it has to be something with the url in the <a href=""> but when i put the route that passport gives me, example: /auth/facebook, my aplication does nothing... well it does something, send me to the homepage :c
here is my code so far on the backend side
const FacebookStrategy = require('passport-facebook').Strategy;
const session = require('express-session');
const secret = require('../config/database')
const user = require('../models/user')
module.exports = function(app, passport){
app.use(passport.initialize());
app.use(passport.session());
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: false }
}));
passport.serializeUser(function(user, done) {
token = jwt.sign({email: user.email}, secret, {expiresIn : '24h'});
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use(new FacebookStrategy({
clientID: '350645212059140',
clientSecret: '8a990aec6db37cc3535f4223c235c427',
callbackURL: "http://localhost:4200/auth/facebook/callback",
profileFields: ['id','displayName','email']
},
function(accessToken, refreshToken, profile, done) {
console.log(profile);
// User.findOrCreate(..., function(err, user) {
// if (err) { return done(err); }
// done(null, user);
// });
done(null, profile)
}
));
app.get('/auth/facebook',passport.authenticate('facebook', { scope: 'email' }));
app.get('/auth/facebook/callback' , passport.authenticate('facebook', {failureRedirect: '/login'}), function(res, res){
if (err) {
console.log(err)
}else{
res.send('wi')
}
})
return passport;
}
my question is, how can i implement this on the fronted side, remember angular 4 :)
Here is pseudo code for this.
Step 1: When you are submitting your form using ngSubmit call a function for instance passportLogin().
Step 2: Now in your component use this function and do an HTTP post request to your node js(express js) URL, for example, auth/login.
Step 3: In the server side write a routing
var express = require('express'),
router = express.Router();
module.exports = function(passport){
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/auth/success',
failureRedirect: '/auth/failure'
}));
}

Node.js, express, passport authentication "Bad Request"

I'm using Cloud 9 to setup a basic social media website and I am having trouble with registration and authentication of users. I'm using Node.js, express and passport for authentication, and mongoDB as a database.
// PASSPORT Setup //
app.use(require("express-session")({
secret: "I am the best",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
// INDEX Page
app.get("/", function(req, res) {
res.render("landing-page");
});
// REGISTER NEW
app.get("/register", function(req, res) {
res.render("user/register");
});
// REGISTER CREATE
app.post("/register", function(req, res) {
var user = req.body.user;
var newUser = new User({
username: user.email,
firstName: user.firstName,
lastName: user.lastName,
});
User.register(newUser, user.password, function(err, user) {
if(err) {
console.log(err);
return res.render("user/register");
}
passport.authenticate("local")(req, res, function() {
res.redirect("/");
});
});
});
// Login routes
app.get("/login", function(req, res) {
res.render("login");
});
app.post("/login", passport.authenticate("local", {
successRedirect: "/",
failureRedirect: "/login"
}) , function(req, res) {
});
// Logout route
app.get("/logout", function(req, res) {
req.logout();
res.redirect("/");
});
However whenever I run this, when I sign up a new user, it gives me a webpage with just "Bad Request", however the user is created in the database.
Look at this answer; the bad request is not a problem with your passport method: that indicates the request you try to make is not correct:
Did you set the head at: Content-Type: application-json?
Also update the bodyParser to the last version. This solved a similar problem I had.

Nodejs passport, not getting user object in route

Following the tutorial here
Auth.js
var passport = require("passport"),
LocalStrategy = require("passport-local").Strategy;
passport.use(new LocalStrategy(
function(username, password, done){
console.log("----", username, password, "----"); //this works fine, get the proper values here.
if(username === "admin" && password === "sw") {
return done(null, {username: "admin"});
}
return done(null, false);
}
));
passport.serializeUser(function(user, done){
done(null, user.username);
});
passport.deserializeUser(function(username, done){
done(null, {username: username});
});
module.exports = passport;
app.js (the relevant bits)
var passport = require("./auth")
var users = require('./routes/users');
.
.
.
app.use('/users', users);
app.post('/', passport.authenticate("local", {
failureRedirect: "/",
successRedirect: "/users"
}));
user route
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function (req, res, next) {
console.log(req.user);
res.render('users', {
title: 'Routed !'
});
});
module.exports = router;
Most of the code works fine, it posts and routes correctly, but, req.user is undefined in the users route, and I'm not able to figure out why.

Authenticating an express app with Passport - Expressjs Passportjs

I have an express app that I am trying to authenticate with passport-local. Here is my express app:
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'this is a string' }));
app.use(passport.initialize());
app.use(passport.session());
client = new pg.Client(connectionString);
client.connect();
passport.use(new LocalStrategy(
function(username, password, done) {
var query = client.query('SELECT * FROM users WHERE EMAIL = $1', [username], function(err, result){
if(err) {
console.log("Error");
return done(err);
}
if(!result.rows.length > 0) {
console.log("No users");
return done(null, false, { message: 'User not found'});
}
if(result.rows[0].password !== password) {
console.log("incorrect password");
return done(null, false, { message: 'Password Incorrect'});
}
console.log('authenticated');
return done(null, result.rows[0]);
});
}
));
passport.serializeUser(function(user, done) {
'use strict';
console.log('serialize');
console.log(user);
done(null, user.email);
});
passport.deserializeUser(function(id, done) {
'use strict';
console.log('deserialize');
User.findById(id, function(err, user) {
done(err, user);
});
});
app.post('/login', passport.authenticate('local'), function(req, res) {
'use strict';
console.log(req.user.username);
});
app.listen(port, function() {
'use strict';
console.log('Listening on:', port);
});
I then hit the /login url with this json in my body: {username: 'jason#gmail.com', password: 'password }. I go through the LocalStrategy function and then in the serialize function it makes it to the done function and then just hangs. I get no errors or additional logging, the connection just stays open and control is not given back to the caller. I never receive a http status, it just hangs.
I think it is a problem with my session, but I do not understand what to do next?
Ok, could you try a redirect there? It looks like your session / auth is ok, if you get a proper username at that point.
app.post('/login', passport.authenticate('local', {
successRedirect: '/somewhere_intern',
failureRedirect: '/login'
}));

Categories