#node.js #jwt #passport.js
Вопрос:
Это мои слушатели.:
{
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:APXZrYtAxMnQuOI-XFJ2h-bh9UlXLGvU.4R7DScHcCIaL0qHdl/ugEs/ABOf1ZgcypFGIhQep/Mo; 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 — Неавторизованный при аутентификации по паспорту-jwt:
Я не могу найти решение для устранения этой проблемы, пожалуйста, помогите мне! Большое вам спасибо!
Ответ №1:
токен, похоже, не содержит утверждений эмитента и аудитории о
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
}
Комментарии:
1. Я удалил: выбор.эмитент = «accounts.examplesoft.com»; выбирает.аудитория = «yoursite.net»; и попробовал еще раз, проблема все еще имеет
Ответ №2:
Я исправил свою проблему, заново настроив паспорт, паспорт-местный, паспорт-jwt и используя:
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
Еще один ниже не работает, я не знаю, почему:
opts.jwtFromRequest = ExtractJwt.fromHeader("Authorization");
opts.jwtFromRequest = ExtractJwt.fromBodyField("token");
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme("Bearer");