Home > Software engineering >  Passport JS Cannot read properties of undefined (reading 'initialize')
Passport JS Cannot read properties of undefined (reading 'initialize')

Time:11-16

Running into an error when implementing Passport.js for authentication. The sessions collection has data parsing to it, however, I get this error:

TypeError: Cannot read properties of undefined (reading 'initialize')
    at Authenticator.initialize (\server\node_modules\passport\lib\authenticator.js:130:26)
    at Layer.handle [as handle_request] (\server\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (\server\node_modules\express\lib\router\index.js:317:13)
    at \server\node_modules\express\lib\router\index.js:284:7    
    at Function.process_params (\server\node_modules\express\lib\router\index.js:335:12)
    at next (\server\node_modules\express\lib\router\index.js:275:10)
    at session (\server\node_modules\express-session\index.js:479:7)
    at Layer.handle [as handle_request] (\server\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (\server\node_modules\express\lib\router\index.js:317:13)
    at \server\node_modules\express\lib\router\index.js:284:7 

My index.js file contains the following:

// Route Variables
const loginRoute = require("./routes/api/login");

/*
    ==MIDDLEWARE==
*/
// Express Parsing Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Passport Auth Middleware
require("./config/passport");

/*
    ==SESSION SETUP==
*/

const sessionStore = MongoStore.create({
  mongoUrl: process.env.MONGO_URL,
});

app.use(
  session({
    secret: process.env.SECRET,
    resave: false,
    saveUninitialized: true,
    store: sessionStore,
    cookie: {
      maxAge: 1000 * 60 * 60 * 24,
    },
  })
);

// Initialize Passport and Use Session for Serialize/Deserialization
app.use(passport.initialize);
app.use(passport.session());

/*
    ==ROUTES==
*/
// User Route
app.use("/api", loginRoute);

When routing to /api/login, the login file contains the following:

const router = require("express").Router();
var passport = require("passport");

router.post(
  "/login",
  passport.authenticate("local", {
    failureRedirect: "/login",
    successRedirect: "/dashboard",
  })
);

module.exports = router;

And finally, my passport middleware file:

const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const bcrypt = require("bcrypt");
const User = require("../models/User");

const verifyCallback = (username, password, done) => {
  User.findOne({ username: username })
    .then((user) => {
      if (!user) {
        return done(null, false);
      }

      // Validate Password
      bcrypt.compare(password, user.password).then((isMatch) => {
        if (isMatch) {
          return cb(null, user);
        } else {
          return cb(null, false);
        }
      });
    })
    .catch((err) => {
      done(err);
    });
};

const strategy = new LocalStrategy(verifyCallback);

passport.use(strategy);

passport.serializeUser((user, done) => {
  done(null, user.id);
});

passport.deserializeUser((userId, done) => {
  User.findById(userId)
    .then((user) => {
      done(null, user);
    })
    .catch((err) => done(err));
});

This appears to be one of those errors where I don't know where it is coming from or hitting. It only throws and error when hitting my submit button for my login form. Other than that, it initializes fine. I've looked over the passport.js documentation, and everything is in order where it should be.

My front end calls this function when hitting the submit button:

const handleOnSubmit = (e) => {
    e.preventDefault();

    login(data)
      .then((response) => {
        toast.success(response.data.message);
        setData({ username: "", password: "" });
        navigate("/dashboard");
      })
      .catch((err) => {
        if (err.response) {
          toast.error(err.response.data.message);
        } else if (err.request) {
          toast.error(err.request);
        } else {
          toast.error(err.message);
        }
      });
  };

and that calls the login function from my loginAPI.js file on my front end which contains the following:


const instance = axios.create({
  baseURL: "http://localhost:8000/api/",
  timeout: 1000,
});

export async function login(data) {
  if (!data.username || !data.password) {
    return Promise.reject(new Error("Data is missing"));
  }

  return await instance.post("/login", data);
}

CodePudding user response:

The problem is in this line in index.js:

app.use(passport.initialize);

You should call function initialize() and NOT property initialize. Change your code like this:

app.use(passport.initialize());
  • Related