Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ionic app hasValidToken() is always false (android fails, ios works) #1457

Open
hvma411 opened this issue Dec 21, 2024 · 0 comments
Open

Ionic app hasValidToken() is always false (android fails, ios works) #1457

hvma411 opened this issue Dec 21, 2024 · 0 comments

Comments

@hvma411
Copy link

hvma411 commented Dec 21, 2024

Describe the bug
So, we have an Ionic Angular app for Android and iOS. We use angular-oauth2-oidc package with our server keycloak for users authentication. We noticed today that signing in doesn't work for Android version of our app (we don't know how long it does not work). We tested both platforms (code exactly the same) and iOS works fine, but android fails with token.

What is the flow?

  1. User clicks button for google or fb login
  2. App opens inApp browser by @capacitor/browser with keycloak website
  3. User can choose between signing in with google, facebook or just typing username and password
  4. After his selection keycloak redirects to app
  5. If token method hasValidToken() returns true then app flow is going to redirect user to other app screens

What is the problem on Android but works fine for iOS?

  1. Above 1, 2, 3, 4 steps works fine
  2. When app is back after redirection then the hasValidToken() returns always false
  3. User is not redirected to other app screens (screens for authenticated user)
  4. When user clicks again on google or fb login buttons then flow is repeated without step 3 because keycloak knows that this user is already signed in so redirection is beeing made to app
  5. After redirection app sometimes is minimized (not always and there are no native or js bugs visible in logcat and dev tools console)

Expected behavior
Everything should work fine as it works for iOS. It worked fine before we noticed it and none code changes has been made in this part of app for about 2 years

Desktop (please complete the following information):

  • OS: Android
  • Browser: Ionic App (@capacitor/browser is used for opening keycloak from oauth methods)
  • Version [e.g. 22]: "angular-oauth2-oidc": "^15.0.1"

Code flow

  1. Plugin init is beeing made in app.module.ts like this:
const authConfig: AuthConfig = {
	issuer: 'issuer url here',
	requireHttps: true,
	redirectUri: 'our redirect uri',
	clientId: 'our client id',
	responseType: 'code',
	revocationEndpoint: 'revoke endpoint',
	showDebugInformation: true,
	useSilentRefresh: true,
	openUri: (uri) => {
		Browser.open({ url: uri });
	},
};

const initializeAuth = (
	oauthService: OAuthService,
	authService: AuthService,
	storageService: StorageService
  ): (() => Promise<void>) => async () => {
	  await storageService.init();
	  oauthService.configure(authConfig);
	  oauthService.setupAutomaticSilentRefresh();
	  authService.addAppUrlOpenListener();
	  return oauthService
		.loadDiscoveryDocumentAndTryLogin()
		.then(() => {
		  console.log('OAuth discovery document loaded');
		})
		.catch((error) => {
		  console.error('Error loading discovery document:', error);
		});
	};
	
	
	
...other providers in module
{ provide: APP_INITIALIZER, useFactory: initializeAuth, multi: true, deps: [OAuthService, AuthService, StorageService] },
...other providers in module

Config is fine, storageService.init() also works fine and no bugs here

  1. addAppUrlOpenListener method looks like this
	addAppUrlOpenListener = (): void => {
		App.addListener('appUrlOpen', async (event) => {
			const url = new URL(event.url);
			this.loggerService.sendLog('App URL opened', { url: event.url });

			this.zone.run(async () => {
				const queryParams: Params = {};
				for (const [key, value] of url.searchParams.entries()) {
					queryParams[key] = value;
				}
				this.router.navigate([], { relativeTo: this.activatedRoute, queryParams }).then(() => {
					this.oauthService.tryLogin().then((result) => {
						if (this.hasValidAccessToken) {
							this.handleAfterLoginActions();
						}
					});

				});

			});
		});
	};
  1. And also we have authOnAppInit method that is fired on app init in app.component.ts to check if user is already logged in. Console logs provided here are just for debugging this problem
	authOnAppInit = (): void => {
		this.oauthService
			.loadDiscoveryDocumentAndTryLogin({
				onTokenReceived: (info) => {
					console.log('Token received callback:', info);
				},
				onLoginError: (error) => {
					console.error('Login error:', error);
				},
			})
			.then((result) => {
				this.hasValidAccessToken = this.oauthService.hasValidAccessToken();
				const accessToken = this.oauthService.getAccessToken();
				const accessTokenExpiration = this.oauthService.getAccessTokenExpiration();

				console.log('Try login result:', result);
				console.log('Access Token:', accessToken || 'No access token');
				console.log('Access Token Expiration:', accessTokenExpiration ? new Date(accessTokenExpiration) : 'No expiration');
				console.log('Has Valid Access Token:', this.hasValidAccessToken);

				if (this.hasValidAccessToken) {
					this.handleAfterLoginActions();
				}
			})
			.catch((error) => {
				console.error('Error during app initialization login check:', error);
			});

		this.oauthService.events.subscribe((event) => {
			console.log('OAuth event received:', event,);

			this.loggerService.sendLog('OAuth event', { event });
			this.hasValidAccessToken = this.oauthService.hasValidAccessToken();
			if (this.hasValidAccessToken) {
				this.handleAfterLoginActions();
			}
		});
	};

So, once again - for Android above console logs are:

  1. Try login result - true (so as far as I understand it means that login succeed)
  2. Access token - null
  3. Access token expiration - null
  4. Has valid access token - false
  5. OAuth event received - OAuthSuccessEvent {type: 'discovery_document_loaded', info: {...}}

We were debugging it for a few hours and as I wrote above, there are no errors in any of these method of plugin or even native errors from android logcat

Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant