反向代理背后的 keycloak-nodejs-connect express.js 应用程序

问题描述

我为 Express JS 创建了一个带有 Keycloak 中间件的 node.js 应用程序,众所周知,它“适用于我的计算机”。

const Keycloak = require('keycloak-connect')
const express = require('express')
const session = require('express-session')
const app = express()

const LOGIN_PATH = '/login'
const logoUT_PATH = '/logout'
const SESSION_STORE_PASS = '123456789012345678901234567890!!!'

const server = app.listen(3000,function () {
    const host = server.address().address
    const port = server.address().port
    console.log('Example app listening at http://%s:%s',host,port)
})

app.get('/',function (req,res) {
    res.redirect(LOGIN_PATH)
})

// Create a session-store to be used by both the express-session
// middleware and the keycloak middleware.
const memoryStore = new session.MemoryStore()
app.use(session({
    secret: SESSION_STORE_PASS,resave: false,saveUninitialized: true,store: memoryStore
}))

const kcoptions = {
    "realm": "nodejs-example","realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2njsSAVcWEQMVhJ31LwIDAQAB","auth-server-url": "http://localhost:8080/auth","ssl-required": "external","resource": "nodejs-connect","public-client": true
}
console.log("Starting Keycloak connector with options: ",kcoptions)
const keycloak = new Keycloak({store: memoryStore},kcoptions)

app.use(keycloak.middleware({
    logout: logoUT_PATH,// <-- this is supposed to delete the session and log you out from KC as well
    admin: '/'
}))

app.get('/login',keycloak.protect(),async function (req,res) {
    let token
    try {
        const grant = await keycloak.getGrant(req,res)
        token = grant.access_token
        console.log(`Found token ${token}`)
    } catch (e) {
        console.log("Unable to find the token in KC response ",req.session)
        throw new Error(e)
    }
    const userProfile = await keycloak.grantManager.userInfo(token)
    console.log("Found user profile:",userProfile)

    res.header("Content-Type",'application/json')
    return res.send(JSON.stringify(userProfile,null,4))
})

此应用程序侦听端口 3000,但问题是浏览器将通过反向代理(端口 80)访问它。而且我无法让中间件将正确的“redirect_uri”查询参数发送到 Keycloak。它总是放置一个与本地服务器正在侦听的相同端口 3000 的 URL。

我发现 redirection-url 设置了 in the documentation,但我在 Github 存储库中没有找到该字符串的证据。

解决方法

keycloak-nodejs-connect 存储库中的一些代码分析,redirect_uri 查询参数为 merely assembled from the incoming request,假设应用程序可直接访问。

这个问题会影响登录和注销阶段。 因此 - 不幸的是 - 没有办法在现实情况下使用这个库(涉及反向代理或负载平衡器)。

更不用说文档中描述的功能与实际实现的功能之间奇怪的脱节。