无法转到下一个中间件 - NodeJS
Can't go to the next middleware - NodeJS
我正在使用 express
并且 router
来创建一个带有 public 和私有路由的服务器。要访问专用路由,用户必须登录并发送 JWT
令牌。令牌很好,但我无法将用户重定向到私有路由。
const express = require('express');
const jwt = require('jsonwebtoken');
const authRouter = require('./auth');
const usersRouter = require('./users');
const router = express.Router();
router.use(authRouter);
const accessTokenSecret = '4-8-15-16-23-42';
const privateRoutes = ['/user'];
const checkPublicOrPrivate = (req, res, next) => {
privateRoutes.forEach(route => {
if (req.path.includes(route)) {
return authorization(req, res, next);
}
});
return next();
};
const authorization = (req, res, next) => {
const { token } = req.headers;
if (token) {
jwt.verify(token, accessTokenSecret, (err, user) => {
if (err) {
return res.status(403).send('Forbiden, access denied');
}
console.log(user); //{ username: 'username', iat: 1603288443 }
return next(); //Should go to the next middleware
});
}
return res.status(403).send('Bad message') //But always hits this message or the 404 one
};
router.use(checkPublicOrPrivate);
router.use(authorization); //Also tried without this line
router.use(usersRouter);
router.use(function(req, res, next) {
res.status(404).send('404 not found!');
});
router.use(function(err, req, res, next) {
res.status(500).send('Server error');
});
module.exports = router;
那是因为jwt.verify
是异步的(有回调函数)。
在验证您的令牌时,代码会继续执行。下一行要执行的是res.status(403).send('Bad message')
,所以它总是被执行。
解决方案是用 else
语句
换行
const authorization = (req, res, next) => {
const { token } = req.headers;
if (token) {
jwt.verify(token, accessTokenSecret, (err, user) => {
if (err) {
return res.status(403).send('Forbiden, access denied');
}
console.log(user);
return next();
});
} else { // add 'else'
res.status(403).send('Bad message'); // This line will only be executed if there's no token
}
};
你应该尝试类似的东西
// the middleware
authenticateToken = function (req, res, next) {
const cookie = new Cookie(req ,res , {})
const token = cookie.get('access_token',{signed:false})
if (token == null) res.redirect('login',401); //TODO: redirect to login with a small message
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err) {
authMethods.refreshToken(req,res,next);
}else{
req.user = user
next()
}
})
}
然后在你的路线上
// the route ...
router.get('/', authenticateToken, function (req, res, next) {
if (!req.user.email) {
res.render('login', { message: "please login again" });
}
const userEmail = authMethods.data.dailyReportNameTable(req.user.email)
console.log(userEmail)
res.render(userEmail)
});
我正在使用 express
并且 router
来创建一个带有 public 和私有路由的服务器。要访问专用路由,用户必须登录并发送 JWT
令牌。令牌很好,但我无法将用户重定向到私有路由。
const express = require('express');
const jwt = require('jsonwebtoken');
const authRouter = require('./auth');
const usersRouter = require('./users');
const router = express.Router();
router.use(authRouter);
const accessTokenSecret = '4-8-15-16-23-42';
const privateRoutes = ['/user'];
const checkPublicOrPrivate = (req, res, next) => {
privateRoutes.forEach(route => {
if (req.path.includes(route)) {
return authorization(req, res, next);
}
});
return next();
};
const authorization = (req, res, next) => {
const { token } = req.headers;
if (token) {
jwt.verify(token, accessTokenSecret, (err, user) => {
if (err) {
return res.status(403).send('Forbiden, access denied');
}
console.log(user); //{ username: 'username', iat: 1603288443 }
return next(); //Should go to the next middleware
});
}
return res.status(403).send('Bad message') //But always hits this message or the 404 one
};
router.use(checkPublicOrPrivate);
router.use(authorization); //Also tried without this line
router.use(usersRouter);
router.use(function(req, res, next) {
res.status(404).send('404 not found!');
});
router.use(function(err, req, res, next) {
res.status(500).send('Server error');
});
module.exports = router;
那是因为jwt.verify
是异步的(有回调函数)。
在验证您的令牌时,代码会继续执行。下一行要执行的是res.status(403).send('Bad message')
,所以它总是被执行。
解决方案是用 else
语句
const authorization = (req, res, next) => {
const { token } = req.headers;
if (token) {
jwt.verify(token, accessTokenSecret, (err, user) => {
if (err) {
return res.status(403).send('Forbiden, access denied');
}
console.log(user);
return next();
});
} else { // add 'else'
res.status(403).send('Bad message'); // This line will only be executed if there's no token
}
};
你应该尝试类似的东西
// the middleware
authenticateToken = function (req, res, next) {
const cookie = new Cookie(req ,res , {})
const token = cookie.get('access_token',{signed:false})
if (token == null) res.redirect('login',401); //TODO: redirect to login with a small message
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err) {
authMethods.refreshToken(req,res,next);
}else{
req.user = user
next()
}
})
}
然后在你的路线上
// the route ...
router.get('/', authenticateToken, function (req, res, next) {
if (!req.user.email) {
res.render('login', { message: "please login again" });
}
const userEmail = authMethods.data.dailyReportNameTable(req.user.email)
console.log(userEmail)
res.render(userEmail)
});