-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
getServerSession is null in Next.js API routes (within the app directory) #7423
Comments
Im also seeing this behaviour when fetching ( |
This is expected, based on your reproduction. The issue in your case (and likely the same for your @freshtechs) is that you are invoking a Route Handler via
import { headers } from "next/headers"
// ...
const response = await fetch(getApiUrl("api/projects"), {
method: "GET",
headers: headers()
}) In your case, option 1 makes more sense. |
@balazsorban44 Thanks so much for the reply. I can confirm that I tried the option 2 and it works fine. However, I'm getting the following TypeScript error: Type 'ReadonlyHeaders' is not assignable to type 'HeadersInit | undefined'.
Type 'ReadonlyHeaders' is missing the following properties from type 'Headers': append, delete, set I'm guessing that this error arises because the Next.js headers are only read-only for now. Any way in which I can resolve this other than ignoring it? Regarding option 1, do you recommend that I use Prisma directly in the server components like the following instead of the API Route? export default async function ProjectIndexPage() {
- const response = await fetch(getApiUrl("api/projects"), {
- method: "GET",
- cache: "no-store",
- headers: headers(),
- });
- const projects: Project[] = await response.json();
+ const projects = await prisma.project.findMany({
+ where: {
+ creatorId: "1",
+ },
+ });
return (..)
} |
Thinking ahead of you. 😉 vercel/next.js#49075 My recommendation would be to just extract the Route Handler into a function like If you worry about performance, check out https://beta.nextjs.org/docs/data-fetching/fetching#data-fetching-without-fetch and https://beta.nextjs.org/docs/data-fetching/caching#per-request-caching |
Wonderful @balazsorban44 thanks for clarifying ✅ |
fwiw, I can retrieve auth state in a route handler using a CredentialsProvider. Here is my /game/[...path]/route.ts that passes on requests. This works on vercel w/ next 13.4.4 and next-auth 4.22.1
|
Are there any downsides with using route handler to wrap external api:s, such as prisma or firebase? versus just having a separate function as you said. Any performance differences? I am thinking that, if i use route handler to wrap my firebase data getter, i can then simply treat this as a normal endpoint and use fetch with its features such as cache config. or is going to cause cache issues and simply not going to work? I know it is possible to use cache(), revalidate, etc. as you linked. But I feel like using fetch is the prioritized way, and also more straight forward and clean. |
|
makes sense, thanks! |
@balazsorban44 I have a simple project firebase + next-auth app, it works perfectly signin in with the GoogleProvider, getServerSession(authOptions) gives me the session correctly, but when using CredentialsProvider it is null, I'm not using fetch anywhere, I'm just trying to get the serversession from within the app folder root page.tsx, here is my auth file:
Any idea why? also the adapter only works with GoogleProvider. The console.log('ses', session) is always null when using Credential provider. |
@felipe-ff same issue, i did following this for credentials login: using database strategy, but it seems the adapter.getSession is currently problematic for firebase adapter. |
I can't even import getServerSession: "Cannot find module 'next-auth/next' or its corresponding type declarations." has anyone else encountered this? I am so confused |
Hi @balazsorban44. Can you please give an example for option 1? I'm calling the import { authOptions } from "@/lib/auth";
import { getServerSession } from "next-auth";
const page = async ({}) => {
const session = await getServerSession(authOptions);
return (
<>
<pre>{JSON.stringify(session)}</pre>
</>
);
};
export default page; I can see the below error in the server console,
let me know if you need more info |
It worked in dev mode, but not in production. Vercel is showing me this error log: [Error]: Headers cannot be modified. Read more: https://nextjs.org/docs/app/api-reference/functions/headers |
I worked around this by getting jwt token instead in RSC, const jwt = await getToken({
// `getToken` only need these attributes, to make it compatible with app router
// This code is copied from `getServerSession`
req: {
headers: Object.fromEntries(headers() as Headers),
cookies: Object.fromEntries(
cookies()
.getAll()
.map((c) => [c.name, c.value])
)
} as unknown as NextRequest
}); |
Hello, I'm having a similar problem with server components using Next Auth with the Firebase Auth service. Error: Error: Cannot destructure property 'user' of '(intermediate value)' as it is null. Server component: export default async function RSC() {
const { user } = await getAuthSession()
return (
<>
</>
)
} On the client, once the user is authenticated I pass the firebase token to the signIn() function. I'm exporting the getServerSession in a separate auth-option.js file. import CredentialsProvider from "next-auth/providers/credentials"
import { auth as serverAuth } from "@/lib/firebase-admin"
import { getServerSession } from "next-auth"
export const authOptions = {
providers: [
CredentialsProvider({
credentials: {},
authorize: async ({ idToken }, _req) => {
if (idToken) {
try {
const decoded = await serverAuth.verifyIdToken(idToken)
return { ...decoded }
} catch (error) {
throw new Error(error)
}
}
return null
},
}),
],
callbacks: {
async jwt({ token, user }) {
let t = {}
let u = {}
if (token) t = token
if (user) u = user
return { ...t, ...u }
},
async session({ session, token }) {
session.user.emailVerified = token.emailVerified
session.user.uid = token.uid
return session
},
},
session: {
strategy: "jwt",
maxAge: 12 * 60 * 60 * 180,
},
secret: process.env.NEXTAUTH_SECRET,
}
export const getAuthSession = () => getServerSession(authOptions) The code was working fine and suddenly stopped working. Same behavior with Next 13 and 14. useSession() function works fine. PS: I couldn't get the firebase adapter to work and I don't get any errors so I can't debug. |
|
Changing |
Next Auth uses cookies. Request from a server component strip cookies. So I moved the db call into the server component. Helpful link: nextauthjs/next-auth#7423 (comment)
Next Auth uses cookies. Request from a server component strip cookies. So I moved the db call into the server component. Helpful link: nextauthjs/next-auth#7423 (comment)
Environment
Reproduction URL
https://github.com/ghoshnirmalya/the-fullstack-app
Describe the issue
The following code always returns
null
if I doconsole.log(session)
when the code is present inside the Next.js API Routes within the app directory:You can find the relevant code here.
However, the following code from the React Server Components returns the correct data:
The
session
in the above case is something like the following:You can find the relevant code here.
How to reproduce
DATABASE_URL='mysql://database-url' NEXT_PUBLIC_VERCEL_URL=127.0.0.1:3000 NEXTAUTH_SECRET=some-secret NEXTAUTH_URL=http://127.0.0.1:3000 GOOGLE_CLIENT_ID=google-client-id GOOGLE_CLIENT_SECRET=google-client-secret
npx prisma db push && npx prisma generate
Expected behavior
The
session
should return the correct object from the API Routes. Theconsole.log(session)
should return something like the following:The text was updated successfully, but these errors were encountered: