diff --git a/examples/react-router/src/router/router.tsx b/examples/react-router/src/router/router.tsx index d51dc79..30742e9 100644 --- a/examples/react-router/src/router/router.tsx +++ b/examples/react-router/src/router/router.tsx @@ -25,18 +25,25 @@ export const router = createBrowserRouter([ async function protectedRouteLoader({ request }: LoaderFunctionArgs) { const oidc = await getOidc(); - if (!oidc.isUserLoggedIn) { - // Replace the href without reloading the page. - // This is a way to make oidc-spa know where to redirect the user - // if the authentication process is successful. - history.pushState({}, "", request.url); + if (oidc.isUserLoggedIn) { + return null; + } - // After the successful login the user will be redirected to location.href (here). - // location.href is request.url because we replaced the href above. - await oidc.login({ doesCurrentHrefRequiresAuth: true }); + await oidc.login({ + // The loader function is invoked by react-router before the browser URL is updated to the target protected route URL. + // Therefore, we need to specify where the user should be redirected after the login process completes. + redirectUrl: request.url, - // Never here, the login method redirects the user to the identity provider. - } + // Explanation: + // The 'doesCurrentHrefRequiresAuth' parameter informs oidc-spa whether it is acceptable to redirect the user to the current URL + // if the user abandons the authentication process. This is crucial to prevent the user from being immediately redirected + // back to the login page when pressing the back button from the login pages. + // If the user navigated directly to the protected route (e.g., by clicking a link to your application from an external site), + // then the current URL requires authentication. + // Conversely, if the user navigated from an unprotected route within your application to the protected route, + // then the current URL does not require authentication. + doesCurrentHrefRequiresAuth: window.location.href === request.url + }); - return null; + // Never here, the login method redirects the user to the identity provider. } diff --git a/examples/tanstack-router-file-based/src/routes/protected.tsx b/examples/tanstack-router-file-based/src/routes/protected.tsx index 638813d..dd1aaac 100644 --- a/examples/tanstack-router-file-based/src/routes/protected.tsx +++ b/examples/tanstack-router-file-based/src/routes/protected.tsx @@ -6,7 +6,17 @@ import { createFileRoute } from "@tanstack/react-router"; export const Route = createFileRoute("/protected")({ component: ProtectedPage, - beforeLoad: protectedRouteLoader + beforeLoad: async () => { + const oidc = await getOidc(); + + if (oidc.isUserLoggedIn) { + return; + } + + await oidc.login({ + doesCurrentHrefRequiresAuth: true + }); + } }); function ProtectedPage() { @@ -60,15 +70,3 @@ function ProtectedPage() { ); } - -async function protectedRouteLoader() { - const oidc = await getOidc(); - - if (oidc.isUserLoggedIn) { - return null; - } - - await oidc.login({ - doesCurrentHrefRequiresAuth: true - }); -} diff --git a/examples/tanstack-router/src/router/router.tsx b/examples/tanstack-router/src/router/router.tsx index 2c0acee..70f7202 100644 --- a/examples/tanstack-router/src/router/router.tsx +++ b/examples/tanstack-router/src/router/router.tsx @@ -11,7 +11,7 @@ const protectedRoute = createRoute({ getParentRoute: () => rootRoute, path: "protected", component: ProtectedPage, - beforeLoad: protectedRouteLoader + beforeLoad: beforeLoadProtectedRoute }); const routeTree = rootRoute.addChildren([indexRoute, protectedRoute]); @@ -24,11 +24,11 @@ declare module "@tanstack/react-router" { } } -async function protectedRouteLoader() { +async function beforeLoadProtectedRoute() { const oidc = await getOidc(); if (oidc.isUserLoggedIn) { - return null; + return; } await oidc.login({