AxaFrance / oidc-client

Light, Secure, Pure Javascript OIDC (Open ID Connect) Client. We provide also a REACT wrapper (compatible NextJS, etc.).
MIT License
597 stars 160 forks source link

Callback does not redirect back to the requested url #779

Closed masterbater closed 2 years ago

masterbater commented 2 years ago

Issue and Steps to Reproduce

Requesting to url /profile if unauthenticated it will go to the oidc provider to initiate login, then it will redirect to callback , but during testing it didnt redirect to profile its just stuck to Authentication complete You will be redirected to your application. Is there a config to set to redirect after the callback? Do you store the requested url like localstorage or cookie then use that to redirect after callback ?

Versions

 5.8.0-alpha0

Config

 export const configuration = {
  client_id: "testingapp-auth",
  redirect_uri: window.location.origin + "/authentication/callback",
  silent_redirect_uri:
    window.location.origin +
    "/authentication/callback/authentication/silent-callback", // Optional activate silent-signin that use cookies between OIDC server and client javascript to restore the session
  scope: "openid profile email offline_access roles",
  authority: "http://oidcprovider.com/apps/testingapp",
    service_worker_relative_url: "/OidcServiceWorker.js",
    service_worker_only: true,
};
masterbater commented 2 years ago

Nevermind, it is customizable I can provide my own component thanks. I found it here. https://github.com/AxaGuilDEv/react-oidc/blob/master/packages/react/README.md

guillaume-chervet commented 2 years ago

Hi @masterbater, thank you very much for the issue? You should not be stuck to that page. It should redirect you to your /profile page. It should be a bug or something like that 😜 Do you have an error message in the console or something else ?

masterbater commented 2 years ago

I just created my own CallbackComponent, I supplied useEffect with idToken and redirect to desired path if its not null.

guillaume-chervet commented 2 years ago

May you copy Paste your work solution here? It will help me to set better defaut component.

Thodor12 commented 2 years ago

@masterbater I'm currently running into the same issue, could you share your solution?

masterbater commented 2 years ago

@masterbater I'm currently running into the same issue, could you share your solution?

Im using react router v6 you can also use history.replace though

import { useOidcIdToken } from "@axa-fr/react-oidc";
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";

const CallbackSuccessComponent = () => {
  const navigate = useNavigate();
  const { idToken} = useOidcIdToken();
  useEffect(() => {
    if (idToken) {
      navigate("/", { replace: true });
      window.location.reload();
    }
  }, [idToken]);

  return <div>CallbackSuccessComponent</div>;
};

export default CallbackSuccessComponent;

`<OidcProvider callbackSuccessComponent={CallbackSuccessComponent} configuration={configuration}

`

You can also save to localstorage the requested url then programatically call the login function then use that to supply in the navigate(requestedUrl, { replace: true });

Thodor12 commented 2 years ago

@masterbater I'm currently running into the same issue, could you share your solution?

Im using react router v6 you can also use history.replace though

import { useOidcIdToken } from "@axa-fr/react-oidc";
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";

const CallbackSuccessComponent = () => {
  const navigate = useNavigate();
  const { idToken} = useOidcIdToken();
  useEffect(() => {
    if (idToken) {
      navigate("/", { replace: true });
      window.location.reload();
    }
  }, [idToken]);

  return <div>CallbackSuccessComponent</div>;
};

export default CallbackSuccessComponent;

<OidcProvider callbackSuccessComponent={CallbackSuccessComponent} configuration={configuration} > <App /> </OidcProvider>

You can also save to localstorage the requested url then programatically call the login function then use that to supply in the navigate(requestedUrl, { replace: true });

It works, thanks.

Although the implementation isn't amazingly spectacular, for example the call to navigate leaves you on that endpoint directly (in my case the router is supposed to redirect / back to /app, which doesn't happen without window.location.reload(), which isn't great, preferably you'd rather not have that reload.

On top of that you'd need to have the OidcProvider within the Router, which shouldn't be required.

@guillaume-chervet You have an idea how we can improve on that?

guillaume-chervet commented 2 years ago

Oh thank you i found where is the bug. I will fix it tonight.

masterbater commented 2 years ago

@masterbater I'm currently running into the same issue, could you share your solution?

Im using react router v6 you can also use history.replace though

import { useOidcIdToken } from "@axa-fr/react-oidc";
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";

const CallbackSuccessComponent = () => {
  const navigate = useNavigate();
  const { idToken} = useOidcIdToken();
  useEffect(() => {
    if (idToken) {
      navigate("/", { replace: true });
      window.location.reload();
    }
  }, [idToken]);

  return <div>CallbackSuccessComponent</div>;
};

export default CallbackSuccessComponent;

<OidcProvider callbackSuccessComponent={CallbackSuccessComponent} configuration={configuration} > <App /> </OidcProvider> You can also save to localstorage the requested url then programatically call the login function then use that to supply in the navigate(requestedUrl, { replace: true });

It works, thanks.

Although the implementation isn't amazingly spectacular, for example the call to navigate leaves you on that endpoint directly (in my case the router is supposed to redirect / back to /app, which doesn't happen without window.location.reload(), which isn't great, preferably you'd rather not have that reload.

On top of that you'd need to have the OidcProvider within the Router, which shouldn't be required.

@guillaume-chervet You have an idea how we can improve on that?

You are right Im just playing around with this library so Im doing some temporary solution. window.location.reload is not needed as long as the token callback is successful hence for the reason why there is checking for idToken and the code I provided you is just barebones and removed some of my logic. As what I have said you can customized what you want to redirect path after callback, just save the path before calling the login hook.

Hope this will get fix for some people doesnt want to customized. Even this get fix you depending on your app you might need some custom logic or UI on its default provided component

masterbater commented 2 years ago

On top of that you'd need to have the OidcProvider within the Router, which shouldn't be required.

Its up on your decision bro just what you have said its not required within Router Im not even showing it in the example codeπŸ˜‚. You can do it even at the entry point component where usually provider lives like index.js or app.js.

There are also some awesome hooks provided by this library to be customizable as much as you want and handling authentication states.

guillaume-chervet commented 2 years ago

It should work in strict mode with react 18 with the last pj lished version now @masterbater @Thodor12 thank you very much for your help.

guillaume-chervet commented 2 years ago

Hi @Thodor12 , @masterbater may we close the issue? Is OK for you?

Thodor12 commented 2 years ago

I can also confirm this is working as intended now, thanks πŸ‘πŸ»