JWT authentification with passport

Not really a question from freecodecamp but i have been working on an api and trying to use jwt auth with passport. Im also having problems with the token login for the blog project. I have created a post route to create the token and when I try to access a protected get route I am getting a 404 error of not found when i use the correct token. If i try the route with a token that isn’t right i get an unauthorized message so the passport function seems to be working. And if i just try the route without using passport to auth it the route works fine so the router and routing is fine. and the console log is showing the correct email in the passport function so it is called correctly

here is the passport function :

opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = process.env.SECRET_KEY; //normally store this in process.env.secret
//opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('JWT')

passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
  console.log(jwt_payload.email)
  if (jwt_payload.email === "c@yahoo.com") {
      return done(null, true)
  }
  return done(null, false)
}) )

and here is the route I am calling

    return res.status(200).send("YAY! this is a protected Route")
}

//exports.protected = (req, res) => { res.send('route working')}

here is the post route generating the token which is generating a token correctly

    let { email, password } = req.body;
    //This lookup would normally be done using a database
    if (email === "c@yahoo.com") {
        if (password === "pass") { //the password compare would normally be done using bcrypt.
            const opts = {}
            opts.expiresIn = 1200;  //token expires in 2min
            const secret = process.env.SECRET_KEY //normally stored in process.env.secret
            const token = jwt.sign({ email }, secret, opts);
            return res.status(200).json({
                message: "Auth Passed",
                token
            })
        }
    }
    return res.status(401).json({ message: "Auth Failed" })
}

and here is a repo:

1 Like

This doesn’t look right.

exports.protected = passport.authenticate('jwt', { session: false }), (req, res) => {
    return res.status(200).send("YAY! this is a protected Route")
}

Try exporting the middleware and adding the handler to the route.

authController.js

exports.protected = passport.authenticate("jwt", { session: false });

api.js

router.get("/protected/", auth_controller.protected, () => {
  console.log("protected callback");
  return res.status(200).send("YAY! this is a protected Route");
});

With that change, I logged in using the email and password, copied the token, and did a GET to the /api/protected/ with the token and it gave back the “YAY! this is a protected Route” response.


I haven’t used passport much and it has been a while. I’m not sure the correct way to export the middleware and handler at the same time from the controller but it might have to be as middleware. This seems to work as well but I can’t say if it’s the correct way of doing it. Copilot kind of wrote it for me.

exports.protected = (req, res, next) =>
  passport.authenticate("jwt", { session: false }, (err, user, info) => {
    if (err) {
      return next(err);
    }
    if (!user) {
      return res.status(401).json({ message: "Auth Failed" });
    }
    return res.status(200).json({ message: "Auth Passed" });
  })(req, res, next);
router.get("/protected/", auth_controller.protected);

But I assume you can also export the middleware and handler separately and use them as such.

1 Like

yeah i just ended up doing that and it is working thanks

1 Like

Cool, which one the first or the second version?

1 Like

I created a new route and passed the passport.authecate to that so now all the router routes in it authenticate with the token.