我有一个负责授权的中间件:loopback-auth-jwt,我想将它应用于大多数端点,但不是全部。应该公开一些端点,但是如果请求具有访问令牌,则应该将其用于身份验证。所以我写了一个中间件,应该检查令牌,如果它存在授权用户,否则它什么也不做,所以用户将被视为匿名。它在本地环境中完美运行,但在远程服务器上失败。说实话,我甚至不知道如何调试。这是我的中间件(它不是1对1代码,但一般概念在这里):
// Define routes that should be public and not protected by auth0 by default.
const EXCLUDED_ROUTES = [
'/api/projects/',
'/api/tasks/[a-z0-9]*',
'/api/projects/(task)/[a-z0-9]*'
];
module.exports = server => {
const auth0Jwt = require('loopback-auth0-jwt');
const jwtDecode = require('jwt-decode');
const authConfig = {
// ...
};
const auth = auth0Jwt(server, authConfig);
// Check if given URL should be considered as public or private route.
// This function is working as desired.
const isPublicRoute = url => {
let isPublic = false;
EXCLUDED_ROUTES.map(route => route.replace('/', '/')).forEach(pattern => {
const regex = new RegExp(pattern);
if (regex.test(url)) {
isPublic = true;
}
});
return isPublic;
};
// Middleware that depend on the result of isPublicRoute function applies auth0 middleware or not.
const authMiddleware = async (req, res, next) => {
const path = req._parsedUrl.pathname;
if (isPublicRoute(path)) {
// validate reuqest headers
if (!(req.headers && req.headers.authorization)) return next();
// ... some additional checks
const userWithToken = await server.models.User.findOne({where: { email: userEmail }, include: ['accessTokens']});
// no token was found, so we need to login user.
if (!userWithToken.accessToken) {
accessToken = await server.models.User.login({
// data
});
}
if (accessToken) {
req.accessToken = accessToken;
next();
} else {
next();
}
} else {
// route is not public - apply auth0 middelware.
server.use(path, auth.authenticated);
next();
}
};
// apply authMiddleware
server.use(authMiddleware);
server.enableAuth();
};
所以我们已经确定了这个问题。根据环回文档,server.use(path, auth.authenticated)
将添加中间件,但由于它是一个快速中间件,它无法控制中间件执行的顺序,这就是返回随机结果的原因。所以我们把它移到了middleware.json并在auth
阶段应用了这个中间件,它就像一个魅力。