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

withAuthenticationRequired doesn't redirect to previous route after successful login #1324

Open
talpenguin opened this issue Jul 31, 2024 · 4 comments
Labels
question Further information is requested

Comments

@talpenguin
Copy link

According to this component's documentation:

"When you wrap your components in this higher-order component and an anonymous user visits your component, they will be redirected to the login page; after logging in, they will return to the page from which they were redirected."

When trying to access a protected route with no authentication, i'm being redirected to the log-in page as expected.
However, after successful log-in, the user is not redirected to the previous route, but to the homepage (just as a normal log-in).
Using signinRedirectArgs: { redirect_uri: window.location.href } partially resolved the issue, user is redirected back to the route he came from, but this adds some unwanted side effects (query params are added to the url).

Current behaviour:
navigate to domain.com/settings -> Not authenticated -> redirect to log-in -> credentials -> redirect to homepage

Expected behaviour:
navigate to domain.com/settings -> Not authenticated -> redirect to log-in -> credentials -> redirect to domain.com/settings

Shouldn't redirect to previous route work out of the box for withAuthenticationRequired?

@pamapa
Copy link
Member

pamapa commented Aug 20, 2024

You will need to pass onSigninCallback (https://github.com/authts/react-oidc-context/blob/main/src/AuthProvider.tsx#L42), then you can control where to go...

@pamapa pamapa added the question Further information is requested label Aug 20, 2024
@idc77
Copy link

idc77 commented Oct 22, 2024

Can you be more specific, @pamapa ?

const onSigninCallback = (_user: User | void): void => {
    window.history.replaceState(
        {},
        document.title,
        window.location.pathname
    )
}

copied from your comments in AuthProvider.tsx .

createRoot(document.getElementById("root")!).render(
    <AuthProvider {...oidcConfig} onSigninCallback={onSigninCallback}>
        <RelayEnvironmentProvider environment={RelayEnvironment}>
            <React.Suspense>
                <React.StrictMode>
                    <RouterProvider router={router}/>
                </React.StrictMode>
            </React.Suspense>
        </RelayEnvironmentProvider>
    </AuthProvider>
);
import {withAuthenticationRequired} from 'react-oidc-context';

export const AuthGuard = ({component})  => {
    const Component = withAuthenticationRequired(component);
    return <Component/>;
}
            {path: 'create-ad', element: <AuthGuard component={PostCreate}></AuthGuard>},

I think this is a pretty common issue, shouldn't it work like that out of the box?

Ok, so I modified the AuthGuard

import {withAuthenticationRequired} from 'react-oidc-context';

export const AuthGuard = ({component})  => {
    const Component = withAuthenticationRequired(component, {signinRedirectArgs: { redirect_uri: window.location.href }});
    return <Component/>;
}

But I had to explicitly add the http://localhost:5173/create-ad redirect_uri in the IDP (Zitadel in this case).

Well I guess that's solved.
I'm not sure how to use ´withAuthenticationRequired otherwise, fairly new to React.

@pamapa
Copy link
Member

pamapa commented Oct 22, 2024

In withAuthenticationRequired you can specify onBeforeSignin. That is the point before the authentication process, thus you can store (e.g. to sessionStorage to current location like const prevPath = window.location.pathname + window.location.search + window.location.hash;...) here the users current location

/**
* Allows executing logic before the user is redirected to the signin page.
*/
onBeforeSignin?: () => Promise<void> | void;

After the authentication process is finished onSigninCallback is called and there you can restore the previous location (e.g. by looking into sessionStorage and apply like window.location.replace(prevPath);)...

@idc77
Copy link

idc77 commented Oct 23, 2024

import {withAuthenticationRequired} from 'react-oidc-context';

export const AuthGuard = ({component})  => {
    const Component = withAuthenticationRequired(
        component, {
            onBeforeSignin: () => {
                sessionStorage.setItem('pp', window.location.pathname + window.location.search + window.location.hash)
            }
        }
    );
    return <Component/>;
}
const onSigninCallback = (_user: User | void): void => {
    const pp = sessionStorage.getItem('pp')
    if (pp) {
        sessionStorage.removeItem('pp')
        window.location.replace(pp)
    } else {
        window.history.replaceState(
            {},
            document.title,
            window.location.pathname
        )
    }
}

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

No branches or pull requests

3 participants