Búsqueda de sitios web

reactjs - Next-auth: Props a la página indefinidos aunque se pasen desde getServerSideProps


Estoy tratando de pasar la sesión que obtengo de getSession (usando next-auth) como props a una página. Sé que puedo usar useSession() dentro del componente, pero según mi entendimiento esto también debería funcionar y no entiendo por qué no lo hace.

Esto parece ser un problema similar al de esta pregunta, pero no hay respuesta.

Aquí está mi muy básico 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;

He ampliado el tipo de Sesión de next-auth de la siguiente manera (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
  }
}

Según mi comprensión de React y NextJs, el código anterior debería funcionar perfectamente, pero al visitar la página recibo

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 |       

¿Qué estoy haciendo mal?

Respuesta #1

Estaba enfrentando el mismo problema y lo resolví por pura suerte.

Parece que Next.js, a través de sus pageProps, hace uso de la prop session en las páginas. Así que cuando intentamos pasar session directamente desde getServerSideProps, por alguna razón está indefinida en el componente del cliente.

En resumen, simplemente devuelve al usuario desde session, o cambia el nombre de la variable de sesión a otra cosa.

Este es el patrón que estoy usando en toda la aplicación donde necesito protección de autenticación 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,
    },
  };
};

Respuesta #2

Aunque todo se ve bien para mí si tienes un objeto de usuario en la sesión y un id en el objeto de usuario, como mencionaste antes. Entonces, puedes usar cambio opcional.

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

Artículos relacionados