ウェブサイト検索

reactjs - Next-auth: getServerSideProps から渡されたのにページにプロップが未定義


私は、next-authを使用してgetSessionから取得したセッションをページのプロパティとして渡そうとしています。コンポーネント内でuseSession()を使うことはできると知っていますが、私の理解ではこれも動作するはずで、なぜ動作しないのか理解できません。

これはこの質問と同じような問題のようですが、答えはありません。

こちらが私の非常に基本的なpages/settings.tsxです:

import { Card, CardContent, Typography } from "@mui/material";
import { User } from "@prisma/client";
import { GetServerSideProps, NextPage } from "next";
import { getSession } from "next-auth/react";

interface SettingsProps {
  user: User,
}

const Settings : NextPage<SettingsProps> = ({user})=>{
  // in here, user is always undefined...
  return (
    <Card>
      <CardContent>      
        <Typography variant="h3">Settings</Typography>
        <Typography>UserId: {user.id}</Typography>
        <Typography>Created: {(new Date(user.createdAt)).toLocaleDateString()}</Typography>
      </CardContent>
      
    </Card>
  );
};

export const getServerSideProps: GetServerSideProps<SettingsProps> =  async (context) =>{
  const session = await getSession(context);

  if (!session) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    };
  }

  console.log(session.user); // this works and logs the user

  return {
    props: { user: session.user },
  };
};

export default Settings;

次のようにして next-auth の Session 型を拡張しました(types/next-auth.d.ts):

import { User } from "@prisma/client";
import NextAuth from "next-auth";

declare module "next-auth" {
  /**
   * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
   */
  interface Session {
    user: User
  }
}

私のReactとNextJsの理解によれば、上記のコードは問題なく動作するはずですが、ページを訪れると

TypeError: Cannot read properties of undefined (reading 'id')
  13 |       <CardContent>      
  14 |         <Typography variant="h3">Settings</Typography>
> 15 |         <Typography>UserId: {user.id}</Typography>
     |                                  ^
  16 |         <Typography>Created: {(new Date(user.createdAt)).toLocaleDateString()}</Typography>
  17 |       </CardContent>
  18 |       

私は何を間違っているのですか?

回答 #1

私は同じ問題に直面していて、純粋な運でそれを解決しました。

どうやら Next.js は、その pageProps を通じて、ページ内で session プロップを利用しているようです。ですので、getServerSideProps から直接 session を渡そうとすると、なぜかクライアントコンポーネントでは未定義になっています。

要するに、sessionからユーザーを返すか、セッション変数の名前を別のものに変更してください。

これは、SSR認証保護が必要な場所すべてでアプリ全体で使用しているパターンです:

export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
  const session = await unstable_getServerSession(req, res, authOptions);
  const user = session?.user;

  if (!user) {
    return {
      redirect: {
        destination: "/",
        permanent: false,
      },
    };
  }

  return {
    props: {
      user,
    },
  };
};

回答 #2

セッションにユーザーオブジェクトがあり、ユーザーオブジェクトにIDがある場合は、先に述べたように、私にはすべて問題なさそうです。ですので、オプションの変更を使用することができます。

<Typography variant="h3">Settings</Typography>
 <Typography>UserId: {user?.id}</Typography>

関連記事