Stack Exchange
Always returning 401 Unauthorized in passport-jwt
This's my req.hearders:
{
  authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYxMDk2Y2Q1MjViNDU5NDY2MDRmYzhiMSIsImVtYWlsIjoibnZhbmhhaWRhbmdAZ21haWwuY29tIiwiaWF0IjoxNjI4MTQ3NzMyfQ.DSZf03dckfyeA8LmScS1jqymqsSUmSb0f8ywihBmvp0',
  'content-type': 'application/json',
  'user-agent': 'PostmanRuntime/7.28.2',
  accept: '*/*',
  'postman-token': '6072dba7-0985-4dc2-9294-0135868dcbfe',
  host: 'a.seito.backend.utility.api:3000',
  'accept-encoding': 'gzip, deflate, br',
  connection: 'keep-alive',
  'content-length': '212',
  cookie: 'connect.sid=s%3AAPXZrYtAxMnQuOI-XFJ2h-bh9UlXLGvU.4R7DScHcCIaL0qHdl%2FugEs%2FABOf1ZgcypFGIhQep%2FMo; lang=en'
}

Token payload:
{
  "id": "61096cd525b45946604fc8b1",
  "email": "nvanhaidang@gmail.com",
  "iat": 1628260741,
  "exp": 1714660741
}

I tried:
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme("Bearer");
opts.jwtFromRequest = ExtractJwt.fromHeader("authorization");

I was indeed not setting an expiry on the token when signing it
const token = jwt.sign(user, config.secrets.jwt, { expiresIn: 86400 * 7 });

./lib/passport/index.js
const passport = require("passport");
const LocalStrategy = require("./strategy/passport_local");
const JWTStrategy = require("./strategy/passport_jwt");

passport.use("local", LocalStrategy);
passport.use("jwt", JWTStrategy);

module.exports = passport;

./lib/passport/strategy/passport_jwt.js
const config = require("../../../lib/config");
// const passport = require("passport");
const JwtStrategy = require("passport-jwt").Strategy;
const ExtractJwt = require("passport-jwt").ExtractJwt;
let Account = require("../../../database/models").Account;

const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme("Bearer");

opts.secretOrKey = config.passport.secret;
opts.issuer = "accounts.examplesoft.com";
opts.audience = "yoursite.net";

module.exports = new JwtStrategy(opts, async function (jwt_payload, cb) {
  await Account.findOne({ email: jwt_payload.email }, function (err, account) {
    if (err) {
      return cb(err, false);
    }
    if (!account) {
      console.log("jwt_payload", jwt_payload);
      return cb(null, false, { message: "Account is not available" });
    }
    if (!account.verifyPassword(password)) {
      return cb(null, false, { message: "Incorrect password." });
    }
    var account_result = {
      id: account[config.database.underscoreId],
      name: account.name,
      email: account.email,
    };
    console.log(account_result);
    return cb(null, account_result);
  });
});

./lib/passport/strategy/passport_local.js
const config = require("../../../lib/config");
const LocalStrategy = require("passport-local").Strategy;
const jwt = require("jsonwebtoken");

const Account = require("../../../database/models").Account;

const opts = {
  usernameField: "login_email",
  passwordField: "login_password",
  session: true,
};

module.exports = new LocalStrategy(opts, async function (
  email,
  password,
  callback
) {
  console.log(email, password);
  await Account.findOne({ email: email }, function (err, account) {
    if (err) return callback(err, false);

    if (!account) {
      return callback({ message: "Account not found" }, false, {
        message: "Account is not available",
      });
    }

    if (!account.comparePassword(password)) {
      return callback(null, false, {
        message: "Incorrect password",
      });
    }
    let account_result = {
      id: account[config.database.underscoreId],
      email: account.email,
    };
    account_result.token = jwt.sign(account_result, config.passport.secret, {
      expiresIn: config.passport.expiresIn,
    });
    account_result.name = account.name;

    return callback(null, account_result);
  });
});

./routes/index.js
require("dotenv").config();
let express = require("express");
const { __ } = require("i18n");
let router = express.Router();
const passport = require("passport");

router.get(
  "/",
  passport.authenticate("jwt", { session: false }),
  async function (req, res, next) {
    console.log(req.err);
    if (req.is("application/*") || req.is("json")) {
      res.status(200).json({
        success: true,
        message: __("Welcome to") + " " + process.env.APP_NAME,
      });
    } else {
      res.render("index", {
        title: process.env.APP_NAME,
      });
    }
  }
);

module.exports = router;

./app.js
const config = require("./lib/config");
const express = require("express");
const passport = require("./lib/passport");
const cookieParser = require("cookie-parser");
const bodyParser = require("body-parser");
const session = require("express-session");

const app = express();

const indexRouter = require("./routes/index");
const authRouter = require("./routes/auth");

app.set("views", path.join(__dirname, "views"));
app.set("view engine", "pug");

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use(session(config.session));
app.use(cookieParser(config.cookie.secret));

app.use(express.static(path.join(__dirname, "public")));

// passport
passport.serializeUser(function (account, cb) {
  process.nextTick(function () {
    cb(null, { id: account.id, name: account.name, email: account.email });
  });
});
passport.deserializeUser(function (account, cb) {
  process.nextTick(function () {
    return cb(null, account);
  });
});

app.use(passport.initialize());
app.use(passport.session());

// routes
app.use("/", indexRouter);
app.use("/auth", authRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  res.status(404);

  // respond with html page
  if (req.accepts("html")) {
    res.render("errors/404", {
      title: "Not Found" + " - " + config.env.APP_NAME,
      url: req.url,
    });
    return;
  }

  // respond with json
  if (req.accepts("json")) {
    res.render("errors/404", { url: req.url });
    return;
  }

  // default to plain-text. send()
  res.type("txt").send(__("Not found"));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = config.env.NODE_ENV === "dev" ? err : {};

  logger.error("[" + err.name + "] request error: " + err.message);
  // render the error page
  if (config.env.NODE_ENV === "dev") {
    res.status(err.status || 500).render("error");
  } else {
    res.status(err.status || 500).json({
      success: false,
      message: "Internal error. [" + err.name + "] " + err.message,
    });
  }
});

module.exports = app;

Login successfully but response with 401 - Unauthorized when authentication by passport-jwt:

I cannot find out solution to fix this issue, please help me! Thank you so much!

I fixed my issue by re-setup passport, passport-local, passport-jwt and use:
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();


Another below don't work, I don't know why:
opts.jwtFromRequest = ExtractJwt.fromHeader("Authorization");
opts.jwtFromRequest = ExtractJwt.fromBodyField("token");
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme("Bearer");


token doesn't seems to contain issuer and audience claims for
opts.issuer = "accounts.examplesoft.com";
opts.audience = "yoursite.net";

token payload should be
{
  "id": "61096cd525b45946604fc8b1",
  "email": "nvanhaidang@gmail.com",
  "iss": "accounts.examplesoft.com", // ADD THIS!!!
  "aud": "yoursite.net",  // ADD THIS!!!
  "iat": 1628260741,
  "exp": 1714660741
}


I removed:
opts.issuer = "accounts.examplesoft.com";
opts.audience = "yoursite.net";
and tried again, issue stil having
