Home > Software engineering >  Pass req.user.username as a parameter to successRedirect in Passport.js
Pass req.user.username as a parameter to successRedirect in Passport.js

Time:12-01

When a user logs in successfully, I want to redirect them to a route that takes their username as a parameter:

router.post("/login", checkNotAuthenticated, passport.authenticate("local", {
    successRedirect: "/dashboard/"   req.user.username,
    failureRedirect: "/login",
    failureFlash: true,
  })
);
router.get("/dashboard/:username", checkAuthenticated, (req, res) => {
  res.render("dashboard", { user: req.user });
});

When I try this, I get the following error:

successRedirect: "/dashboard/"   req.user.username,                                     
                                 ^
ReferenceError: req is not defined

(I understand why req is not defined, but I am showing this to illustrate what it is I want to do.)

I have tested around with changing the route to the following:

router.post("/login", (req, res) => {
  console.log(req.body.username);    // a test; prints what is expected
  passport.authenticate("local", {
    successRedirect: "/dashboard/"   req.body.username,
    failureRedirect: "/login",
    failureFlash: true,
  });
});

When I login with the details, console.log(...) works as expected and prints the user's name. However, the successRedirect does not works as it just keeps loading. There's no form of output in the console, either.

I then also tried req.user.username (in the most recent route), but it just prints:

TypeError: Cannot read property 'username' of undefined

To finally add, when I console.log(req.body), I get:

[Object: null prototype] { username: 'user1', password: 'user1' }

Is there something I am not understanding?

CodePudding user response:

I'm quoting documentation here:

app.post('/login',
  passport.authenticate('local'),
  function(req, res) {
    // If this function gets called, authentication was successful.
    // `req.user` contains the authenticated user.
    res.redirect('/users/'   req.user.username);
  });

passport.authenticate('local') is acting as a middleware and will call the next function that can access the Req object.

CodePudding user response:

I found a solution (pretty quickly after writing this post). I think it's worth noting, still, in case others are in this position.

router.post(
  "/login",
  passport.authenticate("local", {
    failureRedirect: "/login",
    failureFlash: true,
  }),(req, res) {
    res.redirect("/dashboard/"   req.user.username);
  }
);

I ommitted successRedirect, as a successful login will run the route function anyway; all you have to do is account for the failed login attempts (i.e. failureRedirect, or handle a 401 status code), as you can redirect the user with the req.user now existing.

  • Related