Keycloak的redirect_fragment与react-router hashRouter冲突

问题描述 投票:0回答:2

我的应用程序的用户使用 Keycloak 进行身份验证后遇到了重定向问题。

我的应用程序使用react-router hashRouter。当初始重定向发生时,我得到一个看起来像这样的redirect_fragment:

http://localhost:3000/lol.html?redirect_fragment=%2F&redirect_fragment=%2Fstate%3D1c5900ee-954f-4532-b01c-dcf5d88f07a2%26code%3DKZNXVqQCcIXTCFu2ZIkx4quXa6zJb59zGKpNIhZwfNo.d 2786d1e-67cd-437f-a873-bad49126bad4&redirect_fragment=%2Fstate%3D51a9cb44 -b80a-4c14-8f3d-f04dfdb84377%26code%3Dp5cKQ7xVCR_n1s4ucXZTSE3O1T5lwNri_PBKD07Mt1Y.63364a83-f04f-4e64-a33e-faf00f6cd4ff&redirect_fragment=%2Fstate%3D051 55315-ab60-4990-8d4e-444c7cce9748%26code%3DBxxpf_uMB28rKAQ6MXFTTrL9RE4rC3UtwCMXLu_K1Zo.4ce56da0-8e52-47e3-a0f2-4f982599bb98# /状态=f3e362e4-c030-40ac-80df-9f9882296977&code=8HHTgd3KdlfwcupXR_5nDV0CqZNPV1xdCu3udc6l5xM.97b3ea71-366a-4038-a7ce-30ac2f416807

URL 从此不断增长。我已经阅读了一些帖子,这些帖子表明从 keycloak 进行重定向可能会通过 location.hash 进行客户端路由出现问题...任何想法将不胜感激!

react-router keycloak
2个回答
8
投票

我想我已经明白了!

如果我使用“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);

哇!


0
投票

您可以使用

responseMode:'query'
参数初始化 keycloak 实例。 喜欢

new Keycloak({}).init(let init: KeycloakInitOptions = {
      pkceMethod: 'S256',
      ...
      responseMode: 'query'
    })

它取代了类似

#state=...
的哈希来查询参数
/?state=...

© www.soinside.com 2019 - 2024. All rights reserved.