总是返回 401 Unauthorized in passport-jwt
Posted
技术标签:
【中文标题】总是返回 401 Unauthorized in passport-jwt【英文标题】:Always returning 401 Unauthorized in passport-jwt 【发布时间】:2021-10-11 12:34:09 【问题描述】:这是我的 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'
令牌负载:
"id": "61096cd525b45946604fc8b1",
"email": "nvanhaidang@gmail.com",
"iat": 1628260741,
"exp": 1714660741
我试过了:
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme("Bearer");
opts.jwtFromRequest = ExtractJwt.fromHeader("authorization");
签名时我确实没有在令牌上设置到期时间
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;
登录成功但响应 401 - 通过 passport-jwt 进行身份验证时未授权:
我找不到解决此问题的解决方案,请帮助我!非常感谢!
【问题讨论】:
【参考方案1】:token 似乎不包含发布者和受众声明
opts.issuer = "accounts.examplesoft.com";
opts.audience = "yoursite.net";
令牌负载应该是
"id": "61096cd525b45946604fc8b1",
"email": "nvanhaidang@gmail.com",
"iss": "accounts.examplesoft.com", // ADD THIS!!!
"aud": "yoursite.net", // ADD THIS!!!
"iat": 1628260741,
"exp": 1714660741
【讨论】:
我删除了:opts.issuer = "accounts.examplesoft.com"; opts.audience = "yoursite.net";并再次尝试,问题仍然存在【参考方案2】:我通过重新设置护照、本地护照、护照-jwt 和使用解决了我的问题:
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
下面的另一个不起作用,我不知道为什么:
opts.jwtFromRequest = ExtractJwt.fromHeader("Authorization");
opts.jwtFromRequest = ExtractJwt.fromBodyField("token");
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme("Bearer");
【讨论】:
以上是关于总是返回 401 Unauthorized in passport-jwt的主要内容,如果未能解决你的问题,请参考以下文章
Springboot actuator refresh 和 bus-refresh 总是返回 401 Unauthorized