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

Feat: Logout Funtion & URL #97

Open
loonix opened this issue May 19, 2020 · 23 comments
Open

Feat: Logout Funtion & URL #97

loonix opened this issue May 19, 2020 · 23 comments
Labels
enhancement New feature or request

Comments

@loonix
Copy link

loonix commented May 19, 2020

Describe the Feature

The current logout functionally only cleans any cached tokens but does not log
out of the provider. For that to work we would have to provide a logout URL, which is not supported.

Platform(s) Support Requested

  • Android
  • iOS
  • Web

Describe Preferred Solution

Be able to logout completely from the app, it should clear the app cache and log the user out.

Describe Alternatives

None

Related Code

n/a

Additional Context

Reference: #96

@moberwasserlechner moberwasserlechner added the enhancement New feature or request label May 19, 2020
@moberwasserlechner moberwasserlechner added this to the 2.1.0 milestone May 19, 2020
@loonix
Copy link
Author

loonix commented Jun 1, 2020

Coded a workaround for azure b2c logout, while this feature is not completed:

//(...)
import { Plugins } from '@capacitor/core';
const { Browser } = Plugins;

//(...)
const urlLogout = 'https://XXXXXX.b2clogin.com/tfp/XXXXXX.onmicrosoft.com/b2c_1_sign_in/oauth2/v2.0/logout?client_id=XXXXX-XXXXX-XXXXX-XXXXX&response_type=token&redirect_uri=com.company.app://oauth/redirect&scope=openid%20offline_access%20https://XXXXX.onmicrosoft.com/api/demo.read';

// just opens and closes the browser with the previous URL
    const browser = await Browser.open({ url: urlLogout});
    Browser.close();

// Then run the logout from plugin
  Plugins.OAuth2Client.logout(environment.oauth2Options)
      .then(() => sessionStorage.clear())
      .catch(reason => { console.error('OAuth logout failed', reason); });

@JCASTANO
Copy link

hi, any official solution for this?

@tobium
Copy link

tobium commented Jun 30, 2020

the workaround does not work because login and logout does not use the same browser instance...

@loonix
Copy link
Author

loonix commented Jun 30, 2020

It does work for me, its not a definitive fix though

@tobium
Copy link

tobium commented Jun 30, 2020

how do you do the login? via the plugin (with it's native browser usage?)

Are youz forced to type in your username and password after logging out and logging in again?

@loonix
Copy link
Author

loonix commented Jun 30, 2020

The workaround works for azure b2c, not sure about other types of logins. I have made a repo that is working for logins, I have not impletemented there this workaround, but you can have a picture of how I do it:
https://github.com/loonix/capacitor-oauth2-azure-example/blob/master/src/app/home/home.page.ts

Give it a try and tell us how it goes.

@loonix
Copy link
Author

loonix commented Jul 1, 2020

@tobium you tried in IOS Right? Seems to work on the IOS emulator but not on the device :( . Android works fine on my phone.
Workaround only for android then :(.

~Would be great if this plugin could have the logout, as its kind of a deal-breaker for using it

@moberwasserlechner
Copy link
Collaborator

moberwasserlechner commented Jul 1, 2020

~Would be great if this plugin could have the logout, as its kind of a deal-breaker for using it

PRs are welcome ;)

https://github.com/moberwasserlechner/capacitor-oauth2/blob/master/.github/CONTRIBUTING.md#pull-request-guidelines

@loonix
Copy link
Author

loonix commented Jul 9, 2020

After some digging I found this, not sure if it will help to develop this feature. If I knew how to implement it I would.
Azure-Samples/active-directory-b2c-ios-native-appauth#6

@moberwasserlechner
Copy link
Collaborator

@loonix Thanks for the example. Such hints are very helpful as I need less research when starting to work on this task

@loonix
Copy link
Author

loonix commented Jul 16, 2020

@tobium I was able to logout with IOS but had to increase the timeout specifically for IOS.

const urlLogout = https://${environment.tenantName}.b2clogin.com/tfp/${environment.tenantName}.onmicrosoft.com/${environment.signInPolicy}/oauth2/v2.0/logout?client_id=${environment.clientID}&response_type=token&redirect_uri=${environment.redirectUrl}&scope=openid%20offline_access%20https://XXXX.onmicrosoft.com/api/demo.read;

 // Workaround to get IOS logout
    if(Capacitor.platform === 'ios'){
      await Browser.open({ url: urlLogout }).finally(() => setTimeout(() => Browser.close(), 4000));
      this.onLogoutClick();
      return;
    }

@moberwasserlechner moberwasserlechner modified the milestones: 2.1.0, 2.2.0 Aug 27, 2020
@tjelz
Copy link

tjelz commented Jan 28, 2021

Not able to get it working with any of these solutions, did anyone work out a different way to actually log the user out?

@loonix
Copy link
Author

loonix commented Jan 28, 2021

https://github.com/loonix/capacitor-oauth2-azure-example

Check my repo, and the readme file and see if it helps.

@PieterT2000
Copy link

+1 for this feature

@moberwasserlechner moberwasserlechner modified the milestones: 2.2.0, 3.0.0 Jul 1, 2021
@PragyaSingla
Copy link

The workaround works for azure b2c, not sure about other types of logins. I have made a repo that is working for logins, I have not impletemented there this workaround, but you can have a picture of how I do it:
https://github.com/loonix/capacitor-oauth2-azure-example/blob/master/src/app/home/home.page.ts

Give it a try and tell us how it goes.

I tried same but logout is not working for me. Any solution for logout in android?

@moberwasserlechner
Copy link
Collaborator

moberwasserlechner commented Jul 20, 2021

@PragyaSingla not yet but I try to include this into the upcoming 3.x release, that needs Capacitor 3 as its minimum version.

This is a breaking change so I will not back port it to 2.x.

@moberwasserlechner moberwasserlechner modified the milestones: 3.0.0, 3.1.0 Aug 2, 2021
@moberwasserlechner
Copy link
Collaborator

I'm not able to implement this in 3.0.0 and therefore postpone it.

@SantoshPisini
Copy link

SantoshPisini commented Apr 17, 2022

With this setup I'm able to logout

For iOS
await Browser.open({ url }).finally(() => setTimeout(() => { Browser.close(); }, 1500) );

For Android
await Browser.open({ url }).finally();

Where url = https://{TENANT_NAME}.b2clogin.com/tfp/{TENANT_NAME}.onmicrosoft.com/{USER_FLOW_NAME}/oauth2/v2.0/logout

@DwieDima
Copy link

DwieDima commented Sep 30, 2022

i can confirm that the workaround from @loonix works. For IOS it always works, but for Android it only works if the system browser is Chrome.
If the system browser on Android devices is not Chrome, the logout will not work.
To fix this issue i'm using the Cordova In App Browser for android, where the system browser can be forced.
Here is a working snippet for it with angular:

  import { InAppBrowser } from '@awesome-cordova-plugins/in-app-browser/ngx';
  import { Browser } from '@capacitor/browser';
  import { OAuth2Client } from '@byteowls/capacitor-oauth2';
  import { isPlatform } from '@ionic/angular';

  constructor(private iab: InAppBrowser) {}

  public signOut() {
    const url = 'YOUR_LOGOUT_URL';

    return of(isPlatform('android')).pipe(
      switchMap((isAndroid) => (isAndroid ? this.handleAndroidSignOut(url) : this.handleIosSignOut(url))),
      switchMap(() => from(OAuth2Client.logout(OAUTH_OPTIONS)))
    );
  }

  private handleIosSignOut(url: string) {
    return from(Browser.open({ url })).pipe(
      switchMap(() => from(Browser.addListener('browserPageLoaded', () => {}))), // await page load to make sure logout was called
      switchMap(() => Browser.close())
    );
  }

  private handleAndroidSignOut(url: string) {
    const ref = this.iab.create(url, '_system', 'hidden=yes'); 
    return ref.on('loadstop').pipe(tap(() => ref.close())); // // await page load to make sure logout was called
  }

As a sideeffekt you'll see the Browser popup and close quickly. It would be nice, if this could happen in background for better UX. This should be fixed in the plugin itself.

@DenysAshikhin
Copy link

@DwieDima
That looks exactly what would work for me. I have the app-browser working but I'm not sure where is the .pipe coming from?
I also can't close the window:

let ref = await InAppBrowser.create(
    `https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/logout`,
    "_system",
    "hidden=yes"
  );
ref.close()

The hidden flag isn't making the window hidden, and the .close() isn't closing it. Other than that it does work as a solution....

I'm trying to get this to work on reactJS PWA ionic + capacitor.

@DwieDima
Copy link

@DenysAshikhin try this promise-based snipped:

  public async signOut(): Promise<void> {
    const url = 'your-auth-url';

    if(isPlatform('android')) {
      await this.handleAndroidSignOut(url);
    } else {
      await this.handleIosSignOut(url);
    }

    await OAuth2Client.logout(OAUTH_OPTIONS);
  }

  private async handleIosSignOut(url: string): Promise<void> {
    await Browser.open({ url });
    await Browser.addListener('browserPageLoaded', () => {});
    await Browser.close();
  }

  private async handleAndroidSignOut(url: string): Promise<void> {
    const ref = this.iab.create(url, '_system');
    ref.show();
    await new Promise(resolve => setTimeout(() => resolve, 300));
    ref.close();
  }

@mozzi
Copy link

mozzi commented Jan 19, 2023

@DwieDima Did you only install "@awesome-cordova-plugins/in-app-browser": "^6.3.0",, or "cordova-plugin-inappbrowser": "^5.0.0" too?
It seems npx cap sync doesnt see @awesome-cordova-plugins and only adds inAppbrowser when i also install "cordova-plugin-inappbrowser": "^5.0.0"
Making let ref = await InAppBrowser.create(url,"_system",'hidden=yes'); doesnt open chrome browser by default, but shows browser select dialog
https://user-images.githubusercontent.com/906026/213331694-87da460c-888b-485c-abd7-b63ced064228.png

@moberwasserlechner moberwasserlechner removed this from the 3.1.0 milestone Apr 11, 2023
@noahkriesi
Copy link

I just call 'authorize' again with my logout url. This works for me.

  getAzureB2cOAuth2Options(logout: boolean = false): OAuth2AuthenticateOptions {
    return {
      ...
      authorizationBaseUrl: `https://....onmicrosoft.com/.../oauth2/v2.0/` + (!logout ? 'authorize' : 'logout'),
     ...
    };
  }

...

  logout() {
    GenericOAuth2.authenticate(this.getAzureB2cOAuth2Options(true))
    .then(async response => {
      console.log('OAuth response', response);
    })
    .catch(reason => {
      console.error('OAuth rejected', reason);
    });
  }

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

No branches or pull requests