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

tryKeepExistingSessionAsync and loginCallbackAsync refresh loop in Vue #1426

Open
RonanRobineau opened this issue Jul 24, 2024 · 2 comments
Open

Comments

@RonanRobineau
Copy link

Issue and Steps to Reproduce

On my Vue app, using the vanilla oidc client, I have a loop of refresh when I try to use the loginCallbackAsync or use the tryKeepExistingSessionAsync.

Here is the flow: I got a Pinia store, and I instantialize the oidc client here (with getOrCreate), and 2 actions: login and callback.
Login works fine, but the loginCallbackAsync creates a reload of the page, without any eror (it is un an onMounted function).
Same with tryKeepExistingSessionAsync, I have it on my root component, and it juste reload the page, again and again.

I tried my configuration with the oidc-client-demo, and it works fine.

  • Installed packages: 7.22.20
@guillaume-chervet
Copy link
Contributor

Hi @RonanRobineau , do you have a full sample of code?
Bellow the main react component :
https://github.com/AxaFrance/oidc-client/blob/main/packages/react-oidc/src/OidcProvider.tsx
I am pretty sure it should look pretty the same.

I can try to build a vie implementation if you need it.

@RonanRobineau
Copy link
Author

RonanRobineau commented Jul 25, 2024

Hi @guillaume-chervet ,
I managed to make it work based on the react component indeed. But I think making a wrapper component might not be a Vue standard, let me explain what I did :

  • I used Pinia store as an OIDC store (in order to have a centralized handler)
  • I used actions to log in, log out and callback.
  • I used in my root component the tryKeepExistingSessionAsync .

Making this creates the hard reload.
Here is my OIDCHandler.vue component, wrapping my router-view :

<script setup>
import {OidcClient} from '@axa-fr/oidc-client'
import { ref } from 'vue';

const configuration = {
    client_id: 'xxxxx',
    redirect_uri: window.location.origin + '/oidc/callback',
    silent_redirect_uri: window.location.origin + '/oidc/silent-callback',
    scope: 'openid',
    authority: 'xxxxx',
    refresh_time_before_tokens_expiration_in_second: 40,
    service_worker_relative_url: '/OidcServiceWorker.js',
    service_worker_only: true,
  };

  const href = window.location.href;

  const token = ref(null)
  const vanillaOidc = OidcClient.getOrCreate(() => fetch)(configuration);

  vanillaOidc.tryKeepExistingSessionAsync().then(() => {
    token.value = vanillaOidc.tokens;
    if (token.value) {
      window.document.getElementById('logout').addEventListener('click', logout);
    } else {
      window.document.getElementById('login').addEventListener('click', login);
    }
    if (Math.floor((vanillaOidc.tokens.expiresAt - Date.now() / 1000) * 1000) < 0) {
      login()
    }
  });


  function logout() {
    vanillaOidc.logoutAsync();
  }
  function login() {
    vanillaOidc.loginAsync('/');
  }
  if (href.includes(configuration.redirect_uri)) {
    vanillaOidc.loginCallbackAsync().then(() =>   document.location = localStorage.getItem('lastUrl'))
  }
</script>

<template>
  <slot />
</template>

This is quite a simple one, I took the wrapper idea from the react-oidc and applied the vanillajs behaviour, but it does the job (except that you have to create 2 button with id="login" and id="logout". I don't have the time to create a fully fonctional component like the react one, but I might add some stuff on it and create a PR in order to make it easier for Vue users

Update : adding the login() if the token is expired

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

2 participants