NextJS 14 和 Supabase 通过重定向进行身份验证

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

我有一个 NextJS 14 (Typescript) 应用程序并使用 Supabase 作为 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”,
  • “@supabase/ssr”:“^0.0.9”,
  • “@supabase/supabase-js”:“^2.38.0”,
  • “@类型/节点”:“20.8.10”,
  • “@types/react”:“18.2.36”,
  • “@types/react-dom”:“14.2.18”,
  • “自动前缀”:“10.4.16”,
  • “eslint”:“8.53.0”,
  • “eslint-config-next”:“14.0.1”,
  • “下一个”:“14.0.0”,
  • “皮诺”:“^8.16.1”,
  • “pino-logflare”:“^0.4.2”,
  • “postcss”:“8.4.31”,
  • “反应”:“18.2.0”,
  • “react-dom”:“18.2.0”,
  • “react-redux”:“^8.1.3”,
  • “redux”:“^4.2.1”,
  • “tailwindcss”:“3.3.5”,
  • “打字稿”:“5.2.2”,
  • “zod”:“^3.22.4”

我知道身份验证有效,但不幸的是重定向无效。重新加载页面时,我的中间件会自动重定向经过身份验证的用户。

有人可以帮助我为什么重定向不起作用吗?预先感谢。

redirect next.js supabase
1个回答
0
投票

我自己解决了。我不知道为什么,但是当我将

redirect("/")
放在我的
try
-
catch
块之外时,它可以正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.