I'm new to Next.js and even newer to NextAuth, so I may be missing something obvious. I'm using the next-auth email provider as a magic link. I am able to authenticate and redirect. I can see the cookies in the Application tab of the Chrome dev tools. I can console log the session in my home page getServerSideProps()
like so:
const session = await unstable_getServerSession(context.req, context.res, authOptions)
All of this is working fine ...but then when I hit a protected route, the session is null and I get a 401. Here is partial code for a protected route:
import prisma from 'Utilities/PrismaClient'
import { logDBError } from 'Utilities'
import { unstable_getServerSession } from 'next-auth/next'
import { authOptions } from 'pages/api/auth/[...nextauth]'
export default async function handler (req, res) {
const session = await unstable_getServerSession(req, res, authOptions)
console.log(`SESSION_FROM_BOARD_ROUTE: ${JSON.stringify(session)}`) // SESSION_FROM_BOARD_ROUTE: null
const token = await getToken({ req })
if (!session) {
console.log(401)
return res.status(401).json({ board: {}, tasks: [] })
}
...
// GET
// POST
// etc, etc.
}
Here is my [...nextauth].ts
file:
// src/pages/api/auth/[...nextauth].ts:
import NextAuth from 'next-auth'
import EmailProvider from "next-auth/providers/email";
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import prisma from 'Utilities/PrismaClient'
import type { NextAuthOptions } from 'next-auth'
export const authOptions: NextAuthOptions = {
adapter: PrismaAdapter(prisma),
providers: [
EmailProvider({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD
}
},
from: process.env.EMAIL_FROM
}),
],
}
export default NextAuth(authOptions);
Here is the page that makes the API request (handleFetchData)
import React, { useEffect } from 'react'
import { useDispatch } from 'react-redux'
import Board from 'Components/Screens/Board/Board'
import { useRouter } from 'next/router'
import axios from 'axios'
import { getBaseUrl } from 'Utilities'
import { hydrateTasks } from 'Redux/Reducers/TaskSlice'
const BoardPage = (props) => {
const router = useRouter()
const dispatch = useDispatch()
useEffect(() => {
async function handleRouteChange() {
const { boardId } = router.query
const { board, tasks } = await handleFetchData({ boardId })
dispatch(hydrateTasks({ board, tasks }))
}
handleRouteChange()
}, [router])
return (
<Board {...props}/>
)
}
const handleFetchData = async ({boardId, req}) => {
const baseUrl = getBaseUrl(req)
return axios.get(`${baseUrl}/api/board/${boardId}`, {
withCredentials: true
})
.then(({data}) => data)
.catch(err => { console.log(err)})
}
export async function getServerSideProps ({ query, req }) {
const { boardId } = query
const { board, tasks} = await handleFetchData({boardId, req}) ?? {}
return { props: { board, tasks } }
}
export default BoardPage
Thank you in advance.