I have a simple API route, src/pages/api/me.ts
that simply echoes if the user is logged in or not.
import { NextApiRequest, NextApiResponse } from 'next'
import { getSession } from '../../lib/session'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
let user = getSession();
res.status(200).end((user) ? 'yes' : 'no')
}
The import, ../../lib/session
(`src/lib/session.ts):
import { cookies } from 'next/headers';
import jwt from 'jsonwebtoken'
export const getSession = () => {
const nxtCookies = cookies();
if (nxtCookies.has('wp_session')) {
const cookie = nxtCookies.get('wp_session');
// prints on the server
console.log('this is happening on the server')
let sessionData = jwt.verify(cookie.value, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err) return false;
return user;
});
if (sessionData) return sessionData;
}
return false;
}
When I try to call getSession()
from pages/api/me.ts
, I get an error:
./src/lib/session.ts
You're importing a component that needs next/headers. That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component.
import { cookies } from 'next/headers'; :
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
One of these is marked as a client entry with "use client":
src\lib\session.ts src\pages\api\me.ts
How is this possible? Both are server-sided code.
I even have a server component that uses getSession()
to display user information on the website, and this error is not thrown. I even verified via console.log
that within both that component and getSession()
, that the console prints to the server console. So I am not sure how this is possible.
Specifically, the issue here seems to be the cookie
import from next/headers
.
I believe cookies from next/headers
is only for use in server components. src/pages/api/me.ts
is on the server but is not a server component.
You can access the cookies from a request through req.cookies
, and pass it to your getSession
function.
A possible implementation of this would be:
// src/pages/api/me.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import { getSession } from '../../lib/session'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const user = getSession(req.cookies);
res.status(200).end((user) ? 'yes' : 'no');
}
// src/lib/session.ts
import jwt from 'jsonwebtoken';
export const getSession = (cookies: Partial<Record<string, string>>) => {
const session = cookies.wp_session;
if (session) {
// prints on the server
console.log('this is happening on the server');
const sessionData = jwt.verify(session, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err) return false;
return user;
});
return sessionData;
}
}