Next.js 13和Next/Supabase身份验证出现错误

huangapple go评论55阅读模式
英文:

Error using Next.js13 and Next/Supabase auth

问题

以下是您要翻译的内容:

一旦我登录,就会出现这个问题:
无法解析Cookie字符串:[错误:Edge运行时不支持Node.js的'buffer'模块。
了解更多信息:https://nextjs.org/docs/messages/node-module-in-edge-runtime]。

middleware.ts:

import { createMiddlewareSupabaseClient } from "@supabase/auth-helpers-nextjs";
import { NextResponse } from "next/server";

import { Database } from "./types/supabase";
import type { NextRequest } from "next/server";

export async function middleware(req: NextRequest) {
  const res = NextResponse.next();
  const pathname = req.nextUrl.pathname;

  const supabase = createMiddlewareSupabaseClient<Database>({ req, res });

  const {
    data: { session },
  } = await supabase.auth.getSession();

  if (!session && pathname === "/") {
    const url = new URL(req.url);
    url.pathname = "/login";
    return NextResponse.redirect(url);
  }

  return res;
}

supabase-auth-provider:

"use client";

import { Profile } from "../../types/collections";
import { Session } from "@supabase/supabase-js";
import { useRouter } from "next/navigation";
import { createContext, useContext, useEffect } from "react";
import useSWR from "swr";
import { useSupabase } from "./supabase-provider";
interface ContextI {
  user: Profile | null | undefined;
  error: any;
  isLoading: boolean;
  mutate: any;
  signOut: () => Promise<void>;
  signInWithGithub: () => Promise<void>;
  signInWithEmail: (email: string, password: string) => Promise<string | null>;
}
const Context = createContext<ContextI>({
  user: null,
  error: null,
  isLoading: true,
  mutate: null,
  signOut: async () => {},
  signInWithGithub: async () => {},
  signInWithEmail: async (email: string, password: string) => null,
});

export default function SupabaseAuthProvider({
  serverSession,
  children,
}: {
  serverSession?: Session | null;
  children: React.ReactNode;
}) {
  const { supabase } = useSupabase();
  const router = useRouter();

  // 获取用户
  const getUser = async () => {
    const { data: user, error } = await supabase
      .from("profiles")
      .select("*")
      .eq("id", serverSession?.user?.id)
      .single();
    if (error) {
      console.log(error);
      return null;
    } else {
      return user;
    }
  };

  const {
    data: user,
    error,
    isLoading,
    mutate,
  } = useSWR(serverSession ? "profile-context" : null, getUser);

  // 注销
  const signOut = async () => {
    await supabase.auth.signOut();
    router.push("/login");
  };

  // 使用Github登录
  const signInWithGithub = async () => {
    await supabase.auth.signInWithOAuth({ provider: "github" });
  };

  // 使用电子邮件登录
  const signInWithEmail = async (email: string, password: string) => {
    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });

    if (error) {
      return error.message;
    }

    return null;
  };

  // 刷新页面以同步服务器和客户端
  useEffect(() => {
    const {
      data: { subscription },
    } = supabase.auth.onAuthStateChange((event, session) => {
      if (session?.access_token !== serverSession?.access_token) {
        router.refresh();
      }
    });

    return () => {
      subscription.unsubscribe();
    };
  }, [router, supabase, serverSession?.access_token]);

  const exposed: ContextI = {
    user,
    error,
    isLoading,
    mutate,
    signOut,
    signInWithGithub,
    signInWithEmail,
  };

  return <Context.Provider value={exposed}>{children}</Context.Provider>;
}

export const useAuth = () => {
  let context = useContext(Context);
  if (context === undefined) {
    throw new Error("useAuth必须在SupabaseAuthProvider内部使用");
  } else {
    return context;
  }
};

希望这可以帮助您理解您的问题所在。如果需要更多帮助,请随时提问。

英文:

Once I do the login this problem appears :
Failed to parse cookie string: [Error: The edge runtime does not support Node.js 'buffer' module.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime].

middleware.ts:

import { createMiddlewareSupabaseClient } from &quot;@supabase/auth-helpers-nextjs&quot;;
import { NextResponse } from &quot;next/server&quot;;

import { Database } from &quot;./types/supabase&quot;;
import type { NextRequest } from &quot;next/server&quot;;

export async function middleware(req: NextRequest) {
  const res = NextResponse.next();
  const pathname = req.nextUrl.pathname;

  const supabase = createMiddlewareSupabaseClient&lt;Database&gt;({ req, res });

  const {
    data: { session },
  } = await supabase.auth.getSession();

  if (!session &amp;&amp; pathname === &quot;/&quot;) {
    const url = new URL(req.url);
    url.pathname = &quot;/login&quot;;
    return NextResponse.redirect(url);
  }

  return res;
}

supabase-auth-provider:

&quot;use client&quot;;

import { Profile } from &quot;../../types/collections&quot;;
import { Session } from &quot;@supabase/supabase-js&quot;;
import { useRouter } from &quot;next/navigation&quot;;
import { createContext, useContext, useEffect } from &quot;react&quot;;
import useSWR from &quot;swr&quot;;
import { useSupabase } from &quot;./supabase-provider&quot;;
interface ContextI {
  user: Profile | null | undefined;
  error: any;
  isLoading: boolean;
  mutate: any;
  signOut: () =&gt; Promise&lt;void&gt;;
  signInWithGithub: () =&gt; Promise&lt;void&gt;;
  signInWithEmail: (email: string, password: string) =&gt; Promise&lt;string | null&gt;;
}
const Context = createContext&lt;ContextI&gt;({
  user: null,
  error: null,
  isLoading: true,
  mutate: null,
  signOut: async () =&gt; {},
  signInWithGithub: async () =&gt; {},
  signInWithEmail: async (email: string, password: string) =&gt; null,
});

export default function SupabaseAuthProvider({
  serverSession,
  children,
}: {
  serverSession?: Session | null;
  children: React.ReactNode;
}) {
  const { supabase } = useSupabase();
  const router = useRouter();

  // Get USER
  const getUser = async () =&gt; {
    const { data: user, error } = await supabase
      .from(&quot;profiles&quot;)
      .select(&quot;*&quot;)
      .eq(&quot;id&quot;, serverSession?.user?.id)
      .single();
    if (error) {
      console.log(error);
      return null;
    } else {
      return user;
    }
  };

  const {
    data: user,
    error,
    isLoading,
    mutate,
  } = useSWR(serverSession ? &quot;profile-context&quot; : null, getUser);

  // Sign Out
  const signOut = async () =&gt; {
    await supabase.auth.signOut();
    router.push(&quot;/login&quot;);
  };

  // Sign-In with Github
  const signInWithGithub = async () =&gt; {
    await supabase.auth.signInWithOAuth({ provider: &quot;github&quot; });
  };

  // Sign-In with Email
  const signInWithEmail = async (email: string, password: string) =&gt; {
    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });

    if (error) {
      return error.message;
    }

    return null;
  };

  // Refresh the Page to Sync Server and Client
  useEffect(() =&gt; {
    const {
      data: { subscription },
    } = supabase.auth.onAuthStateChange((event, session) =&gt; {
      if (session?.access_token !== serverSession?.access_token) {
        router.refresh();
      }
    });

    return () =&gt; {
      subscription.unsubscribe();
    };
  }, [router, supabase, serverSession?.access_token]);

  const exposed: ContextI = {
    user,
    error,
    isLoading,
    mutate,
    signOut,
    signInWithGithub,
    signInWithEmail,
  };

  return &lt;Context.Provider value={exposed}&gt;{children}&lt;/Context.Provider&gt;;
}

export const useAuth = () =&gt; {
  let context = useContext(Context);
  if (context === undefined) {
    throw new Error(&quot;useAuth must be used inside SupabaseAuthProvider&quot;);
  } else {
    return context;
  }
};

I've tried checking what the problem is but there´s nothing about it anywhere.

答案1

得分: 2

我在将middleware.js文件放在应用程序目录之外时遇到了这个问题,也许这就是你遇到的问题。

英文:

I had that problem when I put the middleware.js file outside the app directory, maybe that's the problem you have.

huangapple
  • 本文由 发表于 2023年4月17日 03:22:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76029908.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定