2

我是节点上的新手,我有一个带 express 的 rest api,一些端点使用 keycloak-connect 具有 keycloak 安全性。发生错误 403 时,我需要自定义响应,即 json 格式的自定义消息。我使用处理程序来管理其他一些状态,例如 200、201、204、404、500,但是当 keycloak 抛出 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}`);
});
4

2 回答 2

1

问题是 keycloak-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
于 2020-12-29T09:03:56.303 回答
0

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}`);
});
于 2021-08-07T17:38:02.230 回答