Keycloak node.js 适配器不会在注销时使 connect.sid 会话 cookie 无效

Posted

技术标签:

【中文标题】Keycloak node.js 适配器不会在注销时使 connect.sid 会话 cookie 无效【英文标题】:Keycloak node.js adapter doesn't invalidate connect.sid session cookie on logout 【发布时间】:2020-06-05 04:01:05 【问题描述】:

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

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 函数来覆盖adapter's session store code 有帮助。不过好像太复杂了:

    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 配置是否能更好地实现目标?

【问题讨论】:

您遇到了什么样的问题?在 /logoff 之后 cookie 仍然存储在浏览器中的事实应该没什么大不了的。如果服务器已删除该 cookie 的会话。在下一个请求中,Keycloak 应该将您的新用户发送到登录页面,然后刷新 cookie。 你也在用前端keycloak.js吗?还是整个身份验证/授权仅由后端完成? 整个认证/授权仅由后端完成,ui依赖后端 问题是cookie'connect.sid'注销后没有删除 当请求带有旧 cookie 时会发生什么?负责检查会话的逻辑应将其标记为错误的 cookie,并且应启动新的登录过程。 【参考方案1】:

您的想法是正确的,我不确定覆盖 Keycloak 的 unstore 方法是最好的方法(如果您升级 Keycloak,或者如果您想使用 unstoreGrant 删除只是授予,但保留会话的其余部分)。

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

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

【讨论】:

以上是关于Keycloak node.js 适配器不会在注销时使 connect.sid 会话 cookie 无效的主要内容,如果未能解决你的问题,请参考以下文章

Keycloak 及其不同的适配器是不是实现了 Openid Connect Backchannel 注销规范

Keycloak 反向通道注销

带有弹簧靴的keycloak openid单次注销

单次注销在 keycloak 和 spring security 中不起作用

Keycloak 注销不会结束会话

Keycloak注销请求不会注销用户