Search code examples
reactjsnext.jsnext-auth

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

Solution

  • 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()
    }