Keycloak redirect_fragment conflicts with hashRouter with reactive router

+3


source to share


1 answer


I think I figured it out!

The redirect loop seems to stop if I use the hashRouter 'noslash' instead of the default which contains the forward slash.

My urls look like this: localhost:3000/lol.html#client/side/route

instead of this: localhost:3000/lol.html#/client/side/route

Now the redirect now seems to have completed appropriately after one redirect, but now I am facing another issue where the hash portion of my route is not honored by the reactive router ...

EDIT: I solved the second issue

react-router creates a wrapper window.location

that it uses to tell which side of the "client" side of the client it is currently on. I found that this wrapper is out of sync with window.location.

Check the output of this console. This was done immediately after removing the redirect (and the page was blank):

Path history /state=aon03i-238hnsln-soih930-8hsdlkh9-982hnkui-89hkgyq-8ihbei78-893hiugsu

History hash (empty)



window.location pathname /lol.html

window.location hash #users/1

state=blah-blah-blah

in history.pathname is part of the redirect url that keycloak sends back after authorization. You will notice that window.location is updated to the correct path / hash, but this story seems to be one url. Maybe keycloak directly modifies window.location to do this redirect?

I tried using history.push (window.location.hash) to route the hash fragment and update the react router, but got the error "this entry already exists on the stack". Since it is clearly not at the top of the location stack, this led me to believe that the reactive router is comparing window.location to its internal location to figure out where it ultimately is. So how did I get around this?

Instead, I used history.replace()

which just replaces the entry at the top of the stack with the new value, rather than pushing the new entry onto the stack. This also makes sense, since we don't want users who navigate "back" in their browsers to fall back to /state=blah-blah-blah

url <- replace to remove this entry from the history stack.

One final snippet: resource-location for client interaction like window.location has both a pathname and a hash component. HashRouter uses a component history.location.pathname

to track the client side route after the hash in the browser. The equivalent of this in window.location is stored in window.location.hash, so we will use that as the value passed to history.replace () instead of window.location.pathname. This confused me a little, but it makes sense when you think about it.

history-router history also keeps track of its current route with the appended /

instead of the preliminary one #

, as it just treats it like any normal URL. Before I called history.replace()

, I needed to take mine window.location.hash

, replace the leading hash with /

, and then pass that valuehistory.replace()

const slashPath = window.location.hash.replace('#', '/'); history.replace(slashPath);

Phew!

+3


source







All Articles