scxsk0992
scxsk0992

Reputation: 197

nextjs & next-auth getSession() in getServerSideProps with HTTPS not work

I cant use getSession() in getServerSideProps with HTTPS.

is it normal? I try many times.

I will get it if use HTTPS . I cant getSession() in getServerSideProps

__Secure-next-auth.callback-url
__Secure-next-auth.session-token
__Host-next-auth.csrf-toke

if use HTTP and I can getSession() in getServerSideProps is Okay

next-auth.callback-url
next-auth.session-token
next-auth.csrf-token

how can I fixed it on HTTPS getSession() in getServerSideProps?

I run the same code on http or https for test

if run with http, I can get the props.session if run with https, I cannot get the props.session

import { getSession } from 'next-auth/client';

export default function Home(props) {
  console.log(props.session);
  return (
    <div>
      <h1>Server Side Rendering</h1>
    </div>
  );
}
export async function getServerSideProps(context) {
  return {
    props: {
      session: await getSession(context),
    },
  };
}

remark:

  1. I had set the NEXTAUTH_URL in .env
  2. I know I can get getSession() in getInitialProps But I need get session.user.id to fetch database with prisma, the same time prisma need run in getServerSideProps

Upvotes: 16

Views: 81120

Answers (4)

Emdadul Islam
Emdadul Islam

Reputation: 13

Replacing getSession() with getServerSession() solved my issue.

This official link has explained how to use getServerSession()

My Previous Code-snippet was:

import { NextPageContext } from "next";
import { getSession } from "next-auth/react";
export async function getServerSideProps(context: NextPageContext) {
  const session = await getSession(context);
  if (!session) {
    return {
      redirect: {
        destination: "/auth",
        permanent: false,
      },
    };
  }
  return {
    props: {},
  };
}

Now, my code is like:

import { getServerSession } from "next-auth/next";
import { authOptions } from "./api/auth/[...nextauth]";
export async function getServerSideProps(context: any) {
    const session = await getServerSession(context.req, context.res, authOptions)
    if (!session) {
      return {
          redirect: {
              destination: '/auth',
              permanent: false,
          }
      }
    }

    return {
      props: {
          session,
      }
    }
}

Upvotes: 1

JAY THIN
JAY THIN

Reputation: 11

Update: 5/11/2023

react: 18, next: 13.5.4, next-auth: 4.24.4

import type { AppContext, AppProps } from 'next/app';
import { SessionProvider, getSession } from 'next-auth/react';
import type { Session } from 'next-auth';

type TSession = {
  session: Session | null;
};

function App({ Component, pageProps }: AppProps<TSession>) {
  return (
    <SessionProvider session={pageProps.session}>
      <Component {...pageProps} />
    </SessionProvider>
  );
}

App.getInitialProps = async ({ Component, ctx }: AppContext) => {
  let pageProps = {};
  if (Component.getInitialProps) {
    pageProps = await Component.getInitialProps(ctx);
  }

  return {
    pageProps: {
      ...pageProps,
      session: await getSession(ctx)
    }
  };
};

Upvotes: 1

jelmd
jelmd

Reputation: 252

With "next 13.3.4", "next-auth 4.22.1" "react 18.2.0" the following seems to work:

import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
import { getSession } from 'next-auth/react';
import { findUser } from '@/lib/prisma';

export default function Example({ profile: user }:
    InferGetServerSidePropsType<typeof getServerSideProps>)
{
    if (!user) {
        return (
            <>
            <h1>Server-Error</h1>
            <p>Please try again later.</p>
            </>
        )
    }
    //...
    return (
        <>
        <h1>Profile {user.firstname}</h1>
        </>
    );
}

type ProfileSettings = {
    firstname: string,
    middlename: string | null,
    lastname: string,
    nickname: string | null,
    email: string,
};

type ProfileData = {
    profile: ProfileSettings | null
};

export const getServerSideProps:GetServerSideProps<ProfileData> = async (context) => {
    var session = await getSession(context);
    var p: ProfileSettings|null = null;
    if (session?.user?.name) {
        let u = await findUser(session.user.name);
        if (u)
            p = {
                account: u.account,
                firstname: u.firstname,
                lastname: u.lastname,
                nickname: u.nickname,
                email: u.email
            };
    }
    return { props: { profile: p }};
}

Upvotes: 1

razboy
razboy

Reputation: 1028

This behaviour is normal. The values are internal to next-auth. When NEXTAUTH_URL is prefixed with https, cookies will be marked as secure. You can see the behaviour here:

https://github.com/nextauthjs/next-auth/blob/543f812eb32448044d2aa725b623ca1dedbb68a3/src/lib/jwt.js#L115

Internally next-auth will handle session irrespective of http or https.

To configure client-side session you can follow the examples in the documentation:

A complete working example here:

First configure a provider in order to share session between your components.

pages/_app.js

import { Provider } from "next-auth/client"

export default function App({ Component, pageProps }) {
  return (
    <Provider session={pageProps.session}>
      <Component {...pageProps} />
    </Provider>
  )
}

If you need to support authentication during server side rendering as well, you will need.

pages/index.js

import { getSession } from "next-auth/client"

export async function getServerSideProps(ctx) {
  return {
    props: {
      session: await getSession(ctx)
    }
  }
}

Inside your components use the react hook provided by next-auth

import { useSession } from "next-auth/client"

export default function Component() {
  const [session, loading] = useSession()

  if (session) {
    return <p>Signed in as {session.user.email}</p>
  }

  return <a href="/api/auth/signin">Sign in</a>
}

And in the api routes on the server side:

import { getSession } from "next-auth/client"

export default async (req, res) => {
  const session = await getSession({ req })
  res.end()
}

Upvotes: 21

Related Questions