Я создаю приложение внешнего интерфейса, которое использует 2FA в дополнение к JWT для авторизации аутентифицированной учетной записи. Промежуточное программное обеспечение настроено так:
const router = require('express').Router()
const jwt = require('jsonwebtoken')
const exjwt = require('express-jwt')
const jwtMW = exjwt({
secret: 'testing out a secret',
})
const getBearerToken = (header, callback) => {
if (header) {
console.log(header)
const token = header.split(' ')
if (token) {
return callback(null, token[0])
} else {
return callback('Malformed bearer token', null)
}
} else {
return callback('Missing authorization header', null)
}
}
const validateToken = (req, res, next) => {
getBearerToken(req.headers['authorization'], (error, token) => {
if (error) {
return res.status(401).json({ success: false, message: error })
}
jwt.verify(token, jwtMW, (error, decodedToken) => {
if (error) {
return res.status(401).send({
success: false,
error: 'Invalid authorization token',
})
}
if (decodedToken.authorized) {
req.decodedToken = decodedToken
next()
} else {
return res
.status(401)
.send({ success: false, error: '2fa is required' })
}
})
})
}
Я запускаю его на защищенных маршрутах следующим образом:
router.get('/:id/profile', validateToken, (req, res) => {
User.findById(req.params.id)
.then(user => res.json(user))
.catch(err => res.status(400).json('Error: ' + err))
})
РЕДАКТИРОВАТЬ, ДОПОЛНИТЕЛЬНЫЙ МАРШРУТ
И еще один маршрут, который выбирает токен здесь:
router.post('/verifycheck', (req, res) => {
let tel = `+1${req.body.tel}`
const code = req.body.code
getBearerToken(req.headers['authorization'], (error, token) => {
if (error) {
console.log(error)
return res.status(401).json({ success: false, message: error })
}
if (!code) {
return res.status(401).json({
success: false,
message: 'A verification code is required',
})
}
jwt.verify(token, jwtMW, (error, decodedToken) => {
// client refers to Twilio Verify service //
client.verify
.services('xxxxxxxxxxxxxxxxxxxxx')
.verificationChecks.create({ to: tel, code: code })
.then(verification_check => {
console.log(error)
console.log(decodedToken)
if (verification_check.valid) {
decodedToken.authorized = true
console.log(decodedToken)
var token = jwt.sign(decodedToken, jwtMW, {
expiresIn: 129600,
})
return res.json({ verification_check, token })
} else {
return res.status(401).json({
success: false,
message: 'Invalid verification code',
})
}
})
.catch(err => {
res.json(err.message)
console.log(err)
})
})
})
})
И он выдает ошибку, которая приводит к сбою сервера, говоря:
TypeError: next is not a function
at middleware (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\node_modules\express-jwt\lib\index.js:76:16)
at Object.module.exports [as verify] (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\node_modules\jsonwebtoken\verify.js:94:10)
at getBearerToken (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\backend\routes\index.js:109:13)
at getBearerToken (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\backend\routes\index.js:22:20)
at router.post (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\backend\routes\index.js:97:5)
Я вижу, где происходит ошибка, но я ' Я не уверен, как исправить эту ошибку.
EDIT
Я понял, что jwt.verify не принимает обратные вызовы в качестве аргумента. Когда я удалил функцию обратного вызова и запустил функцию проверки в инструкции try / catch, все заработало как положено.
const validateToken = (req, res, next) => {
getBearerToken(req.headers['authorization'], (error, token) => {
if (error) {
return res.status(401).json({ success: false, message: error })
}
let decoded = ''
try {
decoded = jwt.verify(token, 'testing out a secret')
} catch (error) {
return res.status(401).send({
success: false,
error: 'Invalid authorization token',
})
}
if (decoded.authorized) {
req.decodedToken = decoded
next()
} else {
return res
.status(401)
.send({ success: false, error: '2fa is required' })
}
})
}