vercel / next-learn

Learn Next.js Starter Code
https://next-learn-dashboard.vercel.sh/
MIT License
3.68k stars 1.89k forks source link

Chapter 15: login works but redirect doesn't #738

Closed eso0117 closed 3 months ago

eso0117 commented 3 months ago

Hello guys

in the chapter15

I expected that if user matched in login form it would be redirected to /dashboard but it doesn't

I have tried adding NEXTAUTH_URL="http://localhost:3000" on my .env and it doesn't work too

It seems authorized callback doesn't call after authorizing success

the following is project's dependencies

"dependencies": {
    "@heroicons/react": "^2.0.18",
    "@tailwindcss/forms": "^0.5.7",
    "@types/node": "20.5.7",
    "@vercel/postgres": "^0.5.1",
    "autoprefixer": "10.4.15",
    "bcrypt": "^5.1.1",
    "clsx": "^2.0.0",
    "next": "^14.0.2",
    "next-auth": "^5.0.0-beta.19",
    "postcss": "8.4.31",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.3.3",
    "typescript": "5.2.2",
    "use-debounce": "^10.0.1",
    "zod": "^3.22.2"
  },

and the following is my codes

auth.ts

import NextAuth from 'next-auth';
import { authConfig } from './auth.config';
import Credentials from 'next-auth/providers/credentials';
import { z } from 'zod';
import { User } from './app/lib/definitions';
import { sql } from '@vercel/postgres';
import bcrypt from 'bcrypt';

async function getUser(email: string): Promise<User | undefined> {
  try {
    const user = await sql<User>`SELECT * FROM users WHERE email=${email}`;
    return user.rows[0];
  } catch (error) {
    console.error('Failed fetch user:', error);
    throw new Error('Failed to fetch user.');
  }
}

export const { auth, signIn, signOut } = NextAuth({
  ...authConfig,
  providers: [
    Credentials({
      async authorize(credentials) {
        const parsedCredentials = z
          .object({
            email: z.string().email(),
            password: z.string().min(6),
          })
          .safeParse(credentials);

        if (parsedCredentials.success) {
          console.log('[auth.ts] - parsed success');
          const { email, password } = parsedCredentials.data;
          console.log(`[auth.ts] - parsed success ${email} ${password}`);
          const user = await getUser(email);
          if (!user) {
            console.log('HERE??');
            return null;
          }

          console.log(`[auth.ts] - users ${user.email} ${user.password}`);
          const passwordsMatch = await bcrypt.compare(password, user.password);

          if (passwordsMatch) {
            console.log(`[auth.ts] - users matched`);
            return user;
          }
        }

        console.log('Invalid credentials');
        return null;
      },
    }),
  ],
});

auth.config.ts

import type { NextAuthConfig } from 'next-auth';

export const authConfig = {
  pages: {
    signIn: '/login',
  },
  callbacks: {
    authorized({ auth, request: { nextUrl } }) {
      console.log('authorized');
      const isLoggedIn = !!auth?.user;
      const isOnDashboard = nextUrl.pathname.startsWith('/dashboard');
      if (isOnDashboard) {
        if (isLoggedIn) return true;
        return false; // Redirect unauthenticated users to login page
      } else if (isLoggedIn) {
        return Response.redirect(new URL('/dashboard', nextUrl));
      }
      return true;
    },
  },
  providers: [], // Add providers with an empty array for now
} satisfies NextAuthConfig;

and the following is terminal log with above codes

authorized
[auth.ts] - parsed success
[auth.ts] - parsed success user@nextmail.com 123456
[auth.ts] - users user@nextmail.com $2b$10$9B29IvOZIyALAYIYuKJf9u3iGNw10aaQtc3CF8QmA/JpnuFnWTEue
[auth.ts] - users matched
eso0117 commented 3 months ago

I found the cause, the cause was error throwing was not positioned properly like the image

Screenshot 2024-06-09 at 5 57 02 PM

I didn't know next-auth make redirecting using error let me close the issue Thanks

rydensun commented 3 months ago

Man, you really saved my ass!!! I had the same mistake as your and I've been stuck here for hours! Huge thanks!