NextJS - NextAuth:登录重定向到登录页面

问题描述 投票:0回答:1

过去 12 个小时我一直在讨论同一个问题,并且已经准备好了可能所有的在线论坛...没有什么真正适合我的需要。

我已经按照NextAuth和NextJS学习教程设置身份验证,不幸的是,我想在成功登录页面/仪表板后将用户重定向,但默认情况下它会转到/登录并且无法更改它,我尝试更改中间件逻辑,尝试重新验证路径,并尝试了解其工作原理。

登录表单.ts

'use client';

import { useFormState, useFormStatus } from 'react-dom';
import Link from 'next/link';
import { authenticate } from '@/app/actions/login/loginEngine';
import ErrorAlert from '../errorAlert';
import { Button } from '../button';

export default function LoginForm() {

  const [errorMessage, dispatch] = useFormState(authenticate, undefined);
  return (
    <>
  {errorMessage && (
            <ErrorAlert AlertMessage={errorMessage} />
          )}

        <div className="flex min-h-full flex-1 items-center justify-center px-4 py-12 sm:px-6 lg:px-8">
         
        
          <div className="w-full max-w-sm space-y-10">
            <div>
               {/* Include your entreprise logo here */}
              <h2 className="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">
                Sign in to your account
              </h2>
            </div>
            <form className="space-y-6" action={dispatch}>
              <div className="relative -space-y-px rounded-md shadow-sm">
                <div className="pointer-events-none absolute inset-0 z-10 rounded-md ring-1 ring-inset ring-gray-300" />
                <div>
                  <label htmlFor="email-address" className="sr-only">
                    Email address
                  </label>
                  <input
                    id="email-address"
                    name="email"
                    type="email"
                    autoComplete="email"
                    required
                    minLength={6}
                    className="relative block w-full rounded-t-md border-0 pl-4 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-100 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                    placeholder="Email address"
                  />
                </div>
                <div>
                  <label htmlFor="password" className="sr-only">
                    Password
                  </label>
                  <input
                    id="password"
                    name="password"
                    type="password"
                    autoComplete="current-password"
                    required
                    className="relative block w-full rounded-b-md border-0 pl-5 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-100 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                    placeholder="Password"
                  />
                </div>
              </div>

              <div className="flex items-center justify-between">
                <div className="flex items-center">
                  <input
                    id="remember-me"
                    name="remember-me"
                    type="checkbox"
                    className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
                  />
                  <label htmlFor="remember-me" className="ml-3 block text-sm leading-6 text-gray-900">
                    Remember me
                  </label>
                </div>

                <div className="text-sm leading-6">
                  <a href="#" className="font-semibold text-indigo-600 hover:text-indigo-500">
                    Forgot password?
                  </a>
                </div>
              </div>

              <LoginButton />

            </form>

            <p className="text-center text-sm leading-6 text-gray-500">
              Not a member?{' '} <Link href="/register" className="font-semibold leading-6 text-indigo-600 hover:text-indigo-500">Create an account</Link>
            </p>
          </div>
        </div>
    </>
  )
}

function LoginButton() {
  const { pending } = useFormStatus();
  return (
    <div>
      <Button className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
        aria-disabled={pending}>
        Sign in
      </Button>

      <button >
    Log in
</button>
    </div>

  );
}

登录引擎.ts

'use server'
import { AuthError } from 'next-auth';
import { signIn } from '../../../auth';
import { revalidatePath } from 'next/cache';
 
export async function authenticate(
  prevState: string | undefined,
  formData: FormData,
) {
  try {
    await signIn('credentials', formData);
  } catch (error) {
    if (error instanceof AuthError) {
      switch (error.type) {
        case 'CredentialsSignin':
          return 'Invalid credentials.';
        default:
          return 'Something went wrong.';
      }
    }
    throw error;
  }
}

auth.ts

import NextAuth from 'next-auth';
import { authConfig } from './auth.config';
import Credentials from 'next-auth/providers/credentials';
import { z } from 'zod';
import bcrypt from 'bcrypt';
import { getUser } from '@/app/libs/dbCore';


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) {
            const { email, password } = parsedCredentials.data;
            const user = await getUser(email);
            if (!user) return null;

            const passwordsMatch = await bcrypt.compare(password, user.password);
            if (passwordsMatch) return user;
          }

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

auth.config.ts

import { NextAuthConfig } from "next-auth";

export const authConfig = {
  pages: {
    signIn: '/login',
    signOut: '/'
  },
  callbacks: {
    authorized({ auth, request: { nextUrl } }) {
      const isLoggedIn = !!auth?.user;
      const isOnDashboard = nextUrl.pathname.startsWith('/dashboard');
      const isOnSettings = nextUrl.pathname.startsWith('/settings')
      if (isOnDashboard || isOnSettings) {
        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;

谢谢你

我知道有回调选项https://next-auth.js.org/getting-started/client#specifying-a-callbackurl但不符合我的需要...我在我的中使用了不同的逻辑形式...我开始绝望。

reactjs next.js next-auth
1个回答
0
投票

在您的 loginEngine.ts 中,替换:

await signIn('credentials', formData);

与:

await signIn("credentials", {
            formData,
            redirectTo: DEFAULT_LOGIN_REDIRECT
        })
© www.soinside.com 2019 - 2024. All rights reserved.