我的应用程序的用户使用 Keycloak 进行身份验证后遇到了重定向问题。
我的应用程序使用react-router hashRouter。当初始重定向发生时,我得到一个看起来像这样的redirect_fragment:
URL 从此不断增长。我已经阅读了一些帖子,这些帖子表明从 keycloak 进行重定向可能会通过 location.hash 进行客户端路由出现问题...任何想法将不胜感激!
我想我已经明白了!
如果我使用“noslash”hashRouter 而不是包含斜杠的默认值,重定向循环似乎会停止。
我的网址如下所示:
localhost:3000/lol.html#client/side/route
而不是这个:
localhost:3000/lol.html#/client/side/route
重定向现在似乎在一次重定向后适当终止,但现在我遇到了一个不同的问题,其中反应路由器不尊重我的路线的哈希部分...
编辑:我解决了第二个问题
react-router 在
window.location
周围创建一个包装器,它用来告诉它当前位于哪个客户端“页面”。 我发现这个包装器与 window.location 不同步。
检查此控制台输出。这是在重定向解决后立即拍摄的(页面为空白):
历史路径名为
/state=aon03i-238hnsln-soih930-8hsdlkh9-982hnkui-89hkgyq-8ihbei78-893hiugsu
历史哈希为(空)
window.location 路径名为
/lol.html
window.location 哈希为
#users/1
history.pathname 中的
state=blah-blah-blah
是 keycloak 在身份验证后发回的重定向 URL 的一部分。您会注意到 window.location 已更新为正确的路径/哈希,但该历史记录似乎落后于一个 URL。也许keycloak直接修改window.location来执行这个重定向?
我尝试使用history.push(window.location.hash)来推送哈希片段并更新react路由器,但收到错误“该条目已存在于堆栈中”。由于它显然不在位置堆栈的顶部,这让我相信react-router将window.location与其内部位置进行比较,以确定它最终在哪里。那么我是如何解决这个问题的呢?
我使用了
history.replace()
,它只是用新值替换堆栈顶部的条目,而不是将新条目推入堆栈。这也是有道理的,因为我们不希望在浏览器中“返回”导航的用户返回到该 /state=blah-blah-blah
url <-- replace eliminates this entry from the history stack.
最后一点:react-router History.location,与 window.location 一样,都有路径名和哈希组件。 HashRouter 使用
history.location.pathname
组件来跟踪浏览器中哈希后的客户端路由。 window.location中的等效项存储在window.location.hash中,因此我们将使用它作为传递给history.replace()而不是window.location.pathname的值。这让我有点困惑,但仔细想想就明白了。
react-router 历史记录还使用前置的
/
而不是前置的 #
来跟踪其当前路由,因为它只是将其视为任何普通 URL。在调用 history.replace()
之前,我需要取出 window.location.hash
,用 /
替换前导哈希,然后传递该值 history.replace()
const slashPath = window.location.hash.replace('#', '/');
history.replace(slashPath);
哇!
您可以使用
responseMode:'query'
参数初始化 keycloak 实例。
喜欢
new Keycloak({}).init(let init: KeycloakInitOptions = {
pkceMethod: 'S256',
...
responseMode: 'query'
})
它取代了类似
#state=...
的哈希来查询参数/?state=...