如何在NodeJS中自定义密钥斗篷错误消息



我是node的新手,我有一个带有express的rest api,一些端点使用keycapture连接实现keycapture安全。当出现错误403时,我需要一个自定义响应,即json格式的自定义消息。我使用一个处理程序来管理其他一些状态,比如,200、201、204、404、500,但当keycloft抛出403时,我无法工作。

var memoryStore = new session.MemoryStore();
app.use(session({
secret: 'my-secret',
resave: false,
saveUninitialized: true,
store: memoryStore
}));
var keycloak = new Keycloak({
store: memoryStore
});
app.use(keycloak.middleware());
// keycloak security
app.get('/service/secured', keycloak.protect('realm:user'), function (req, res) {
res.json({message: 'secured'});
});
app.get('/service/admin', keycloak.protect('realm:admin'), function (req, res) {
res.json({message: 'admin'});
});
// 404 handler and pass to error handler
app.use((req, res, next) => {    
next(createError(404, 'Not found'));
});
// Error Handler
app.use((err, req, res, next) => { 
// This log never is printed when 403 ocurrs
console.log('Error: ', err); 
res.status(err.status || 500);
res.send({
error : {
status : err.status || 500,
message : err.message
}
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server starter on port ${PORT}`);
});

问题是keycapture connect错误地使用了express中间件。它使用res.end()而不是next(),因此在此之后您什么都不能做。您可以尝试通过添加新的中间件来重写此逻辑。

...
app.use(function(req, res, next) {
res.end = function(body) {
if (res.statusCode === 403 && body === 'Access denied') {
next(body);
} else {
res.send(body);
}
}
});
app.use(keycloak.middleware());
...
// handle error how you want

您可以在初始化前覆盖Keycloak.prototype.accessDenied并抛出新错误,以便您的句柄可以处理。

var memoryStore = new session.MemoryStore();
app.use(session({
secret: 'my-secret',
resave: false,
saveUninitialized: true,
store: memoryStore
}));
// Overriding keycloak access denied to return 401 status code and custom message.
Keycloak.prototype.accessDenied = () => {
// Considering createError will throw new Error.
createError(401, 'Access Denied');
};
var keycloak = new Keycloak({
store: memoryStore
});
app.use(keycloak.middleware());
// keycloak security
app.get('/service/secured', keycloak.protect('realm:user'), function (req, res) {
res.json({message: 'secured'});
});
app.get('/service/admin', keycloak.protect('realm:admin'), function (req, res) {
res.json({message: 'admin'});
});
// 404 handler and pass to error handler
app.use((req, res, next) => {    
next(createError(404, 'Not found'));
});
// Error Handler
app.use((err, req, res, next) => { 
// Now this print with error 401 and message Access Denied
console.log('Error: ', err); 
res.status(err.status || 500);
res.send({
error : {
status : err.status || 500,
message : err.message
}
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server starter on port ${PORT}`);
});

相关内容

最新更新