簡體   English   中英

Next.js useSession 和 SessionProvider 的 13 個和下一個身份驗證問題

[英]Next.js 13 and next-auth issues with useSession and SessionProvider

我正在嘗試制作一個登錄頁面。 在我的 page.tsx 文件中,我收到兩個錯誤之一,具體取決於我是否包含“使用客戶端”; 在我的代碼的頂部。 如果我沒有“使用客戶端”; 我收到此錯誤: Error: React Context is unavailable in Server Components 我收到此錯誤: Error: [next-auth]: useSession must be wrapped in a <SessionProvider />

這是我的 layout.tsx 文件:

`import Image from 'next/image'
import { SessionProvider } from "next-auth/react";
import { ReactNode } from "react";
import React from 'react';

import "./globals.css";
import Link from "next/link";

type Props = {
  children: ReactNode;
  session: any;
};

export default function Layout({ children, session }: Props) {
  return (
    <html lang="en">
      <head />
      <body>
        <div className="mx-auto">
          <div className="flex flex-row flex-wrap">
            <aside className="w-full sm:w-1/3 md:w-1/5 xl:w-1/6 border-r-2 border-[#F845C6]">
              <div className="sticky top-0 p-4 w-full">
                <ul className="flex flex-col overflow-hidden">
                  <li className="m-5 text-center">
                    <Link href="login">LOGO</Link>
                  </li>
                  <li className="m-5 text-center">
                    <Link href="/">Dashboard</Link>
                  </li>
                  <li className="m-5 text-center">
                    <Link href="tasks">Tasks</Link>
                  </li>
                  <li className="m-5 text-center">
                    <Link href="reporting">Reporting</Link>
                  </li>
                </ul>
              </div>
            </aside>

            <div className="w-full sm:w-2/3 md:w-4/5 xl:w-5/6">{children}</div>
          </div>
        </div>
      </body>
    </html>
  );
}

export function getLayout(page: any) {
  const { session } = page.props;

  return (
    <SessionProvider session={session}>
      <Layout session={session}>{page}</Layout>
    </SessionProvider>
  );
}
`
this is the login page.tsx file:


`"use client";
import React from 'react'
import { useSession, signIn, signOut } from 'next-auth/react'
import { getLayout } from '../components/Layout'

export default function Login() {
  const { data: session } = useSession();
  console.log(session);

  if (session) {
    return (
      <div style={{ fontFamily: 'sans-serif', margin: '10px 20px' }}>
        <p>Welcome, {session.user.name}</p>
        <img src={session.user.image} alt="" style={{ borderRadius: '15px', width: '80px', margin: '10px' }} />
        <button onClick={() => signOut()}>Sign out</button>
      </div>
    );
  } else {
    return (
      <div>
        <p>Please sign in</p>
        <button onClick={() => signIn("google", { callbackUrl: '/account' })}>Sign in with Google</button>
      </div>
    );
  }
}

Login.getLayout = function getLayout(page: any) {
  return getLayout(page);
};`

我試圖從一個舊項目轉移到一個使用應用程序目錄的項目。 我試圖將原始 _app.js 文件中的 SessionProvider 代碼添加到根布局,但我沒有任何運氣

對於遇到此頁面的任何其他人,如果您從未解決過該問題,SessionProvider 只需要包裝在服務器呈現布局中使用的客戶端組件中,而不是直接應用於布局中。

制作提供者文件:

"use client";

import { SessionProvider } from "next-auth/react";

type Props = {
  children?: React.ReactNode;
};

export const NextAuthProvider = ({ children }: Props) => {
  return <SessionProvider>{children}</SessionProvider>;
};

然后像這樣在你的根布局中使用它:

type Props = {
  children: ReactNode;
};

export default function RootLayout({ children }: Props) {
  ...
  return (
    ...
    <NextAuthProvider>
      ...
      {children}
      ...
    </NextAuthProvider>
    ...
  );
}

這將使您能夠訪問站點中所有客戶端組件中的 session 上下文,這通常是您想要的。

第一個問題是無法識別您構建布局的方式。

export default function Layout({ children, session }: Props) {
  return (
    <html lang="en">
      <head />
      <body>
        {/* after body element place SessionProvider */}
        <SessionProvider>
          <div className="mx-auto">
            {/* then the rest of jsx or components here */}
          </div>
        </SessionProvider>
      </body>
    </html>
  );
}

useSession是一個鈎子,鈎子只能在客戶端組件中使用。 您可以通過在文件開頭添加use client指令將您的組件轉換為客戶端組件。

或者在服務器組件中,您可以使用getServerSession

import { getServerSession } from 'next-auth'
import { NextAuthOptions } from 'next-auth'

export const authOptions: NextAuthOptions = {
  // your options here
}


const session = await getServerSession(authOptions)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM