Я проверил много ответов в Интернете, но думаю, что делаю и другую ошибку. Мой вопрос строго связан с защитой маршрута /contribute
с использованием JWT (который является запросом POST). Мой API находится в expressjs
. Сначала я нажимаю маршрут /login
с правильными учетными данными и получаю токен. Этот токен я перепроверил на jwt.io и там написано "Неверная подпись".
Вот этот жетон:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0IjoiNWVhZDlkOGY4N2VjMjkwMDE3YzRkODkzIiwiaWF0IjoxNjA3ODczNjY2fQ.H5RI-lOBzfJo4_FgParuJA4ULnJ_An6uihiF31bzNtU
Затем я выбирал маршрут /contribute
с тем же токеном. Вот мой код:
API.js
const express = require('express');
const router = express.Router();
...
const jwt = require('jsonwebtoken');
...
router.post('/login', (req, res) => {
let userData = req.body
User.findOne({ email: userData.email }, (error, user) => {
if (error) {
console.info(error)
} else {
if (!user) {
res.status(401).send('Invalid email')
} else if (user.password !== userData.password) {
res.status(401).send('Invalid password')
} else {
let payLoad = { subject: user._id }; // tried { subject: 'foobar' } also
let token = jwt.sign(payLoad, 'secretKey');
res.status(200).send({ token, userData, user });
}
}
})
})
router.post('/contribute', verifyToken, (req, res) => {
console.info('Pushing new article');
let userPost = req.body;
let post = new Post(userPost);
post.save((error, registeredPost) => {
if (error) {
console.info(error);
} else {
res.status(200).send(registeredPost);
}
})
})
function verifyToken(req, res, next) {
if (!req.headers.authorization) {
return res.status(401).send('Unauthorized request')
}
let token = req.headers.authorization.split(' ')[1];
if (token === 'null') {
return res.status(401).send('Unauthorized request')
}
let payload = jwt.verify(token, 'secretKey')
if (!payload) {
return res.status(401).send('Unauthorized request')
}
req.userId = payload.subject
next()
}
module.exports = router;
Но в тот момент, когда я нажимаю /contribute
, я получаю это:
JsonWebTokenError: неправильно сформирован jwt в Object.module.exports [как проверить] (C:\Users\320050772\Documents\socialcoderapinodejs\node_modules\jsonwebtoken\verify.js:63:17) в verifyToken (C:\Users\320050772\Documents\socialcoderapinodejs\routes\api.js:86:23) в Layer.handle [как handle_request] (C:\Users\320050772\Documents\socialcoderapinodejs\node_modules\express\lib\router\layer.js:95:5) далее (C:\Users\320050772\Documents\socialcoderapinodejs\node_modules\express\lib\router\route.js:137:13) в Route.dispatch (C:\Users\320050772\Documents\socialcoderapinodejs\node_modules\express\lib\router\route.js:112:3) в Layer.handle [как handle_request] (C:\Users\320050772\Documents\socialcoderapinodejs\node_modules\express\lib\router\layer.js:95:5)
Пожалуйста, укажите на мою ошибку.
Я также проверил Postman. Токен сгенерирован, но снова недействителен. Почему мой код генерирует недопустимые токены.
Бро, я проверил твой код, все в порядке, verifyToken
✅ (но не объекты User и Post), убедитесь, что вы правильно отправляете заголовок авторизации, например:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0IjoiMTIzNDQ1IiwiaWF0IjoxNjA3ODgwMjkwfQ.zJbcqM8yBRABxhm5BgQNow1gmzsgUjiLdPdv7Tq5ND4
Я использовал код из вашего примера и немного изменил
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
app.get('/', (req, res) => res.send('123'));
app.post('/login', (req, res) => {
let payLoad = { subject: '123445' };
let token = jwt.sign(payLoad, 'secretKey');
res.status(200).send({ token });
});
app.post('/contribute', verifyToken, (req, res) => {
res.send('i can reach here...');
});
function verifyToken(req, res, next) {
if (!req.headers.authorization) {
return res.status(401).send('Unauthorized request');
}
let token = req.headers.authorization.split(' ')[1];
if (token === 'null') {
return res.status(401).send('Unauthorized request');
}
let payload = jwt.verify(token, 'secretKey');
if (!payload) {
return res.status(401).send('Unauthorized request');
}
req.userId = payload.subject;
next();
}
app.listen(3000, () => console.info('server on 3000'));
Было замечено, что сгенерированный токен действителен. Но он не доходит до бэкэнда с предстоящим следующим вызовом, например, Post of /contribute. показывает какое-то недопустимое значение. Поэтому пусть действительный токен будет получен на Backend, чтобы jwt.varify мог правильно его проверить.
SyntaxError: await допустимо только в асинхронной функции
скопируйте и первую строку = router.post("/login", async (req, res) => {
да я всё скопировал
нет :-( Можем ли мы сделать онлайн-звонок, пожалуйста. Я поделюсь своим экраном.
конечно, мы можем иметь. поделитесь ссылкой на зум
Пожалуйста, присоединяйтесь к этому: us04web.zoom.us/j/…
спасибо, что указали на мою ошибку. Я соответствующим образом обновлю свой код, и вы сможете отредактировать ответ, чтобы я мог его принять. Дай мне немного времени. :-)
Хорошо, @Tanzeel я буду
Я перепроверил на jwt.io и там написано "Неверная подпись" - это обычно бывает, когда не вставляешь секрет или ключ в поле в правой колонке. Не зная ключа, jwt.io не может проверить подпись.