首页 > 解决方案 > Keycloak node.js 适配器不会在注销时使 connect.sid 会话 cookie 无效

问题描述

根据文档, Node.js keycloak-nodejs-connect适配器(4.3 版)用于保护微服务端点的应用程序网关:

var session = require('express-session');
var Keycloak = require('keycloak-connect');

var memoryStore = new session.MemoryStore();
var keycloak = new Keycloak({ store: memoryStore });

但是,在用户登录/注销流程之后,源自express-session的connect.sid cookie仍存储在浏览器中。如果其他用户之后通过同一浏览器登录,则会导致意外问题。

如何connect.sid正确清除 express-session cookie?

通过添加到函数来覆盖适配器的会话存储代码有帮助。但是,它似乎太复杂了:response.clearCookie('connect.sid', { path: '/' });unstore

    var SessionStore = require('keycloak-connect/stores/session-store');

    let store = (grant) => {
        return (request, response) => {
          request.session[SessionStore.TOKEN_KEY] = grant.__raw;
        };
    };

    let unstore = (request, response) => {
        delete request.session[SessionStore.TOKEN_KEY];
        response.clearCookie('connect.sid', { path: '/' });
    };

    SessionStore.prototype.wrap = (grant) => {
        if (grant) {
          grant.store = store(grant);
          grant.unstore = unstore;
        }
    };

一些 keycloak 适配器或 express-session 配置是否更好地实现了目标?

标签: node.jskeycloakexpress-sessionkeycloak-nodejs-connectkeycloak-connect

解决方案


你的想法是正确的,我不确定重写 Keycloak 的unstore方法是最好的方法(如果你升级 Keycloak,或者如果你想用来unstoreGrant删除授权,但保留其余部分,可能会搞砸会议)。

更好的方法是创建一个在您的注销路由上触发的新中间件:

app.use('/logout', (req, res, next) => {
  req.session.destroy();
  res.clearCookie('connect.sid', { path: '/' });
  res.redirect(keycloak.logoutUrl()); // optional
});

推荐阅读