Keycloak login opens in external browser which breaks the flow

Hi all, I’m building a mobile app using Capacitor, I have a web-app hosted at let’s say https://abc.example.com, I want to render the https://abc.example.com in the webView, So for that I have added below code in the Capacitor config

  "server": {
    "url": "https://abc.example.com",
    "cleartext": false
  }

And My app is rendering in the webView in mobile apps, But I have a Sign in button in the web-app, I use keycloak to authenticate users(keycloak-js package)

Problem

The keycloak login page is opening in the default browser of the mobile and not in the webView, the user can log in there, but then it’s redirecting to the localhost#state=… and not in the webview

But I read that there are ways to capture the redirect on your custom redirect URLs and then open the app when you capture it, But the issue is that keycloak-js store the challenge verifier code etc in the instance and if it start the new instance then those will be lost and even though I got the state and code from keycloak, I will not be able to fetch the tokens from it

The other way is, I guess, to do the keycloak auth in the capacitor base app itself and send the tokens to the hosted web-app when rendering it(like store in localstorage and web-app will read it), but the issue with that is I have some pages which do not require authentication, so I cant force authentication when the app is loaded, and so the user need to click on Sign in button to start the authentication but I can’t interrupt it because if I modify the code as to not do the regular flow of opening the keycloak login page then the hosted web-app will break.

So what options do I have? How are you guys handling such situations?

keycloak is designed for a single browser window flow. Splitting it between your WebView and the system browser breaks its state management. Your best option is to handle auth at the native/capacitor layer using Browser Capacitor Plugin API | Capacitor Documentation.

This is the most reliable way to get a secure and working auth flow in your app loading a remote URL.

Hi, sorry for the late reply, I was testing something

So, I am trying to avoid handling of auth at the native/capacitor app itself, and so I hosted my keycloak server at the same host with pathprefix as my frontend, like if the frontend was at https://abc.example.com, now the keycloak server is at https://abc.example.com/auth

Well, the login page is now opening in the webView itself, but when I enter uname/pwd it’s redirecting me to chrome with redirect URL like HTTP://localhost#state

So I forced the redirect_url to https://abc.example.com in keycloak.login({redirectUri: redirect_url})

But it’s still opening it in chrome with the same localhost URL

Let me know if you have any ideas on this, meanwhile I will try the native auth method.

Side note: Keycloak with pathPrefix is working in my web-app, so there is no issue in that setup.

Thanks.

Yeah, that redirect still popping out to localhost even with Keycloak on the same domain. Classic WebView pain point.

It just breaks the flow keycloak-js expects. This is why the native auth approach using deep links and a plugin is pretty much the standard fix – it lets the app grab the login success directly from the OS redirect.

1 Like