在询问我的问题之前需要分享一些背景和设置,所以请原谅文本墙。 =)
我的应用:
http://frontend
是一个SPA,作为NGINX的静态资源(keycloak
)
http://keycloak
服务器在middleware
frontend
是http://middleware
作为API端点与之通信的NodeJS应用(例如:const session = require('express-session')
const memoryStore = new session.MemoryStore()
app.use(session({
secret: 'mySecret',
resave: false,
saveUninitialized: true,
store: memoryStore
}))
const keycloak = require('./auth/keycloak')
app.use(keycloak.middleware({
logout: '/logout'
}))
)。中间件使用keycloak-nodejs-connect(https://github.com/keycloak/keycloak-nodejs-connect)来保护API端点
中间件中的设置代码如下所示:
auth/keycloak.js
const keycloakConfig = {
'realm': 'realmName',
'auth-server-url': `http://keycloak/auth`,
'ssl-required': 'external',
'resource': 'clientName',
'credentials': {
'secret': 'aaaaaaaa-bbbb-cccc-dddd-1a49c9dfbbef'
}
}
module.exports = new Keycloak({store: memoryStore, responseType: 'code'}, keycloakConfig)
中的设置是:
frontend
当用户点击前端的“/ login”链接时,http://middleware/login
会生成一个新标签,新标签会调用middleware
。动机是UI中的现有状态不被触及,所有重定向等都在新窗口中发生。 app.get('/login', keycloak.protect(), (req, res) => {
const keycloakTokens = JSON.parse(req.session['keycloak-token'])
const userInfo = JSON.stringify(decodeToken(keycloakTokens))
res.status(200).send(`<html><head>
<script type="text/javascript">
window.opener.postMessage(${userInfo}, 'http://frontend')
window.close()
</script>
</head></html>`)
})
const decodeToken = ({id_token}) => {
const payload = JSON.parse(atob(id_token.split('.')[1]))
return payload
}
中的代码如下所示:
postMessage
所以我们的想法是,在OIDC跳舞之后,中间件将使用opener
JWT的内容回复询问id_token
到connect.sid
(父)的新标签。
假设1:cookie frontend
中的会话是中间件用来确保用户仍然经过身份验证的内容。这个假设准确吗?
postMessage
中有一个事件监听器监视middleware
并将发送的信息(id_token)保存到localStorage。
问题1:根据上述设置,这是一种正确的登录方式吗?
我想我肯定错过了一些东西,因为keycloak
中的另一条受保护路由导致重定向到frontend
再次告诉我中间件不知道{{1}}已经过身份验证。
问题2:在这种情况下如何注销?只是清除浏览器cookie?
我尝试了示例应用程序(https://github.com/keycloak/keycloak-nodejs-connect/tree/master/example)但是它具有不同的体系结构,浏览器指向中间件域。
如果您正在寻找更多代码段或详细信息,请告诉我们。很乐意提供。