NextJS 14和支持重定向的身份验证

pgx2nnw8  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(114)

我有一个NextJS 14(Typescript)应用程序,并使用Supplement作为Saas后端。
我的app/login/page.tsx文件呈现以下组件:

'use client'
import { useFormState, useFormStatus } from 'react-dom';
import { signInUser } from '@/actions/auth'

const initialState = {
  message: "",
}

function SubmitButton(){
  const { pending } = useFormStatus()

  return (
    <button type="submit" aria-disabled={pending}>Bestätigen</button>
  )
}

export default function SignInForm() {

  const [state, sigInAction] = useFormState(signInUser, initialState)

  return (
    <div>
      <h2>Register!</h2>
      <form action={sigInAction}>
        <div>
          <label htmlFor="email">
            Email
          </label>
          <input
            type="email"
            id="email"
            name="email"
            autoComplete="email"
            required
          />
        </div>
        <div>
          <label htmlFor="password">
            Password
          </label>
          <input
            id="password"
            type="password"
            name="password"
            required
          />
        </div>
        <p aria-live="polite" role="status">
          {state?.message}
        </p>
        <div>
          <SubmitButton/>
        </div>
      </form>
    </div>
  );
}

字符串
actions/auth.ts中的signInUser函数是:

"use server"

import { revalidatePath } from "next/cache";
import { z } from "zod";
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { cookies } from 'next/headers'
import { redirect } from "next/navigation";

export async function signInUser(prevState: any, formData: FormData) {
  console.log("Action")
  const schema = z.object({
    email: z.string().min(1),
    password: z.string().min(1)
  })
  const signUpFormData = schema.parse({
    email: formData.get("email"),
    password: formData.get("password")
  })
  try {
    const cookieStore = cookies()

    const supabase = createServerClient(
      process.env.NEXT_PUBLIC_SUPABASE_URL!,
      process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
      {
        cookies: {
          get(name: string) {
            return cookieStore.get(name)?.value
          },
          set(name: string, value: string, options: CookieOptions) {
            cookieStore.set({ name, value, ...options })
          },
          remove(name: string, options: CookieOptions) {
            cookieStore.set({ name, value: '', ...options })
          },
        },
      }
    )
    const { data, error } = await supabase.auth.signInWithPassword({
      email: signUpFormData.email,
      password: signUpFormData.password,
    })
    if (error) {
      console.log(error)
    }
    
    revalidatePath("/")
    console.log("Should redirect now...")
    redirect("/")
  } catch (e){
    return {message: "Error"}
  }
}


这是我的中间件。ts:

import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
  console.log("Enter Middleware")
  
  let response = NextResponse.next({
    request: {
      headers: request.headers,
    },
  })

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        get(name: string) {
          return request.cookies.get(name)?.value
        },
        set(name: string, value: string, options: CookieOptions) {
          request.cookies.set({
            name,
            value,
            ...options,
          })
          response = NextResponse.next({
            request: {
              headers: request.headers,
            },
          })
          response.cookies.set({
            name,
            value,
            ...options,
          })
        },
        remove(name: string, options: CookieOptions) {
          request.cookies.set({
            name,
            value: '',
            ...options,
          })
          response = NextResponse.next({
            request: {
              headers: request.headers,
            },
          })
          response.cookies.set({
            name,
            value: '',
            ...options,
          })
        },
      },
    }
  )

  await supabase.auth.getSession();
  const {
    data: { user },
  } = await supabase.auth.getUser()
  // if user is not signed in and the current path is not /login redirect the user to /login
  if (!user && !request.nextUrl.pathname.startsWith('/login')) {
    console.log("redirect to /login")
    return NextResponse.redirect(new URL('/login', request.url))
  }

  // if user is signed in and the current path is /login redirect the user to /
  if (user && request.nextUrl.pathname === '/login') {
    console.log("redirect to /")
    return NextResponse.redirect(new URL('/', request.url))
  }

  return response
}

export const config = {
  matcher: ['/', '/login'],
}


我使用以下依赖项:

  • “@reduxjs/toolkit”:“^1.9.7”,
  • “@ supply/ssr”:“^0.0.9”,
  • “@ supplies/supabase-js”:“^2.38.0”,
  • “@types/node”:“20.8.10”,
  • “@types/react”:“18.2.36”,
  • “@types/react-dom”:“18.2.14”,
  • “autoprefixer”:“10.4.16”,
  • “eslint”:“8.53.0”,
  • “eslint-config-next”:“14.0.1”,
  • “next”:“14.0.0”,
  • “pino”:“^8.16.1”,
  • “pino-logflare”:“^0.4.2”,
  • “postcss”:“8.4.31”,
  • “react”:“18.2.0”,
  • “react-dom”:“18.2.0”,
  • “react-redux”:“^8.1.3”,
  • “redux”:“^4.2.1”,
  • “tailwindcss”:“3.3.5”,
  • “typescript”:“5.2.2”,
  • “zod”:“^3.22.4”

我知道身份验证是有效的,但不幸的是重定向不起作用。当重新加载页面时,我的中间件会自动重定向经过身份验证的用户。
有人能帮我为什么重定向不工作吗?提前感谢。

ivqmmu1c

ivqmmu1c1#

我自己解决了这个问题。我不知道为什么,但是当我把重定向(“/”)放在我的try-catch-block之外时,它就可以正常工作了。

相关问题