Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Several Improvements Needed for signIn and signOut Logic in Chapter 15 Adding Authentication of the Official dashboard-app Tutorial #861

Closed
ks4na opened this issue Sep 9, 2024 · 2 comments · Fixed by #983

Comments

@ks4na
Copy link

ks4na commented Sep 9, 2024

currently,The implementation of next-auth Credentials authentication flow in Chapter 15 of the official tutorial works, but it has some flaws that cause several confusion for me and also some other learners. such as

Existing Issues

Based on my observations, the following issues exist with the tutorial's implementation (which can be reproduced in the official live demo):

  1. When navigating from the homepage to the login page and successfully logging in, the user is redirected to the /dashboard page, but the browser's URL does not change and remains as /#. Additionally, the Sign Out button does not work until the page is refreshed, after which the URL displays correctly as .../dashboard and the Sign Out button works as expected.
issues_point_1.mp4
  1. Following the steps in point 1, when clicking the Sign Out button on any page (e.g., /dashboard/customers), the page content updates to the /# page, but the browser's URL does not change. After refreshing the page, the browser URL updates to .../#?callbackUrl=https%3A%2F%2Fnext-learn-dashboard.vercel.sh%2Fdashboard%2Fcustomers.
issues_point_2.mp4
  1. Following the steps in point 2, if the browser URL contains a callbackUrl=... query parameter (e.g., when accessing https://next-learn-dashboard.vercel.sh/dashboard/customers while not logged in, which redirects to the /# page with the callbackUrl), the expected behavior is to be redirected to the callbackUrl page after a successful login. However, after logging in, the user is still redirected to the /dashboard page, and the same issue from point 1 occurs: the browser's URL does not update and remains as .../#?callbackUrl=https%3A%2F%2Fnext-learn-dashboard.vercel.sh%2Fdashboard%2Fcustomers, and the Sign Out button does not work. Refreshing the page resolves the issue.
issues_point_3.mp4

Suggested Improvements

During SignIn

As mentioned in this comment Redirect URL not updating correctly in browser after successful redirect, pass the redirectTo parameter to the signIn() function, and ensure it aligns with the logic in auth.config.ts -> authorized.

The logic in auth.config.ts -> authorized:

// ...

if (isOnDashboard) {
  if (isLoggedIn) {
    return true;
  }
  return false;
} else if (isLoggedIn) {
  return Response.redirect(new URL('/dashboard', nextUrl));
}

// ...

To keep the same logic, the login form should include the redirectTo field, defaulting to /dashboard. If the URL contains a callbackUrl, the field should be set to that value.

modify app/#/page.tsx:

// ...

export default function LoginPage({
  searchParams,
}: {
  searchParams?: {
    callbackUrl?: string;
  };
}) {
  const redirectTo = searchParams?.callbackUrl || '/dashboard'; // <============== get `redirectTo` from search param `callbackUrl`

  return (
    <main className="flex items-center justify-center md:h-screen">
      {/* ... */}

        <LoginForm redirectTo={redirectTo} /> {/* <============== pass `redirectTo` to LoginForm */}
      </div>
    </main>
  );
}

modify app/ui/#-form.tsx:

// ...

export default function LoginForm({ redirectTo }: { redirectTo: string }) {
  // ...

  return (
    <form action={formAction} className="space-y-3">
      {/* ... */}

      <input type="hidden" name="redirectTo" value={redirectTo} /> {/* <============== add `redirectTo` */}

    {/* ... */}
    )
}

During SignOut

In the sidenav.tsx, the redirectTo parameter should be specified. Typically, when signing out, the user should be redirected to the homepage or the login page.

modify app/ui/dashboard/sidenav.tsx:

// ...

export default function SideNav() {
  return (
      {/* ... */}

        <form
          action={async () => {
            'use server';
            await signOut({ redirectTo: '/' }); /* <============== add `redirectTo` */
          }}
        >

      {/* ... */}
    )
}

Verification After the Fixes

minimal reproducible repo: https://github.com/ks4na/nextjs-dashboard/tree/chapter15-improvements

vercel.app preview link

Additional Information

next-auth documentation

For more details on signIn(), signOut(), and redirectTo, see the documentation: signIn(), signOut().

@rodicodi
Copy link

I got a few errors lately that Canary is using the new async server component props...
So.... just a suggestion:

// ...

type PageProps = {
  searchParams?: Promise<{
    callbackUrl?: string;
  }>;
};

export default async function LoginPage(props: PageProps) {
  const searchParams = await props.searchParams;
  const redirectTo = searchParams?.callbackUrl || "/dashboard"; // <============== get `redirectTo` from search param `callbackUrl`

  return (
    <main className="flex items-center justify-center md:h-screen">
      {/* ... */}

        <LoginForm redirectTo={redirectTo} /> {/* <============== pass `redirectTo` to LoginForm */}
      </div>
    </main>
  );
}

@leerob
Copy link
Member

leerob commented Jan 19, 2025

Thank you! Fixing

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants