NVO
NVO

Reputation: 2713

Passport: Unknown authentication strategy "local"

I'm new to NodeJS and I try to build a login/registration system. Registration works fine but I'm currently unable to login.

I find a example app using passport and nodejs, so based on this example I build the registration form and the login form. http://blog.robertonodi.me/node-authentication-series-email-and-password/

When I try to login I get an 'Unknown authentication strategy "local" error'. Can anybody explain what I'm doing wrong?

My code

(edit: added some changes from answers/comments and filenames)

Express config (config/express.config.js)

app.use(session({
    store: new MongoStore({
        url: 'mongodb://' + config.url + ':' + config.port + '/' + config.name
    }),
    secret: 'secretkey',
    key: 'skey.sid',
    resave: false,
    saveUninitialized: false,
    cookie : {
        maxAge: 604800000 //7 days in miliseconds
    }
}));

app.use(passport.initialize());
app.use(passport.session());
require(path.join(__dirname, 'auth.config'))(passport); //Load passport config

app.use(function(req, res, next) {
    req.resources = req.resources || {};
   // res.locals.app = config.app;
    res.locals.currentUser = req.user;
    res.locals._t = function (value) { return value; };
    res.locals._s = function (obj) { return JSON.stringify(obj); };
    next();
})

Passport config (config/auth.config.js)

var path = require('path');

var passport=require('passport');
var User = require(path.join(__dirname, '..', 'models', 'user.model'));

module.exports = function(passport) {

    passport.serializeUser(function(user, done){
        done(null, false);
    });
    passport.deserializeUser(function(id, done){
        console.log("deserializeUser called", id);
        User.findById(id, function (err, user) {
            done(err, user);
        });
    });

    //load strategy files
    require(path.join(__dirname, 'strategies', 'local-strategy'));
    //TODO: Facebook
    //TODO: Twitter
    //TODO: Google
}

Local strategy (/config/strategies/local-strategy.js)

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongoose = require('mongoose');
var User = mongoose.model('User');

module.exports = function () {
    console.log("LocalStrategy called");
    passport.use(new LocalStrategy({
        usernameField : 'username',
        passwordField : 'password'
    },
    function(username, password, done) {
        User.authenticate(username, password, function(err, user) {
            if (err) {
                return done(err);
            }

            if(!user) {
                return done(null, false, {message: 'Invalid username or password'});
            }

            return done(null, user);
        })
    }))
}

Auth Controller (login only) (/controllers/auth.controller.js)

module.exports.loginUser = function(req,res, next) {
    console.log("Auth.config", path.join(__dirname, 'strategies', 'local-strategy'))
   passport.authenticate('local', function (err, user, info) {
       if (err || !user) {
           console.log("Error", info);
           return res.status(400).send(info);
       }

       req.logIn(user, function(err) {
           if (err) {
              return next(err);
              // return res.status(404).send("Username or password incorrect");
           }
       })

       res.status(200).json(user);
   })(req, res, next);
}

Upvotes: 29

Views: 62308

Answers (5)

Adharsh K C
Adharsh K C

Reputation: 1

Add local to your passport.use:

passport.use('local', new localStrategy {
  usernameField: "email",
  passwordField: "password"
}

And add require('./config/passport-config/localStrategy') to the app.js

Upvotes: 0

Enrique Ruvalcaba
Enrique Ruvalcaba

Reputation: 21

I export the passport object like this:

import passport from "passport";
import { LocalStrategy } from "./strategies";

passport.use(LocalStrategy);

export default passport;

And then I imported it in the route where I needed:

import { Router } from "express";
import { login } from "../controllers/auth.controller";
import passport from "../utils/auth";

export const router = Router();

router.post(
  "/login",
  passport.authenticate("local", { session: false }),
  login
);

Notice that I imported passport from "../utils/auth" to use that one that I exported in the first code example.

Upvotes: 0

Ravi Shankar Bharti
Ravi Shankar Bharti

Reputation: 9268

You forgot to import passport config file in your app.js.

import passport config after initializing passport.

app.use(passport.initialize());
app.use(passport.session());
// Add the line below, which you're missing:
require('./path/to/passport/config/file')(passport);

Upvotes: 45

DBertola
DBertola

Reputation: 41

this fix the error. need to use 'local' when you create a new LocalStrategy

passport.use('local', new LocalStrategy({
    usernameField:'useName',
    passwordField: 'password',
    passReqToCallback: true

Upvotes: 4

Eassa Nassar
Eassa Nassar

Reputation: 1230

i have done like this and it worked

$npm install passport-local

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy; /* this should be after passport*/



 passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

Upvotes: 3

Related Questions