cookie not working on server side
Unanswered
Wool sower gall maker posted this in #help-forum
Wool sower gall makerOP
Hello, can someone explain me why i cannot fetch data from my api from the server component while it works when i 'use client'? i use a cookie to validate if the user got access to my api. I just dont understand why its not working on the server side. I authenticated before so the cookie is present when i look in chrome tab application. the print statement in the server side code also shows me the exact and right cookie.
Server:
API:
Client:
API:
Server:
import {cookies} from 'next/headers'
export default async function Menu() {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
guilds.json().then((data) => {
console.log(data);
});
const cookieStore = cookies();
const authCookie = cookieStore.get('connect.sid');
console.log(authCookie);
return <h1>Hello, Menu!</h1>
}API:
Accessing: /api/guilds
User not authenticatedClient:
'use client'
import {cookies} from 'next/headers'
export default async function Menu() {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
guilds.json().then((data) => {
console.log(data);
});
const cookieStore = cookies();
const authCookie = cookieStore.get('connect.sid');
console.log(authCookie);
return <h1>Hello, Menu!</h1>
}API:
Accessing: /api/guilds
Successfully authenticated user115 Replies
Wool sower gall makerOP
so i tried to remove the authentication when i try to access my api using chrome i get my message back
{
"msg": "WORKING"
}if i fetch it on the serverside in next i get this error:
------this is console.log(guilds)--------
Response {
[Symbol(realm)]: { settingsObject: {} },
[Symbol(state)]: {
aborted: false,
rangeRequested: false,
timingAllowPassed: false,
requestIncludesCredentials: false,
type: 'default',
status: 200,
timingInfo: null,
cacheState: '',
statusText: '',
headersList: HeadersList {
cookies: null,
[Symbol(headers map)]: [Map],
[Symbol(headers map sorted)]: null
},
urlList: [],
body: { stream: undefined, source: [Uint8Array], length: 2 }
},
[Symbol(headers)]: HeadersList {
cookies: null,
[Symbol(headers map)]: Map(9) {
'access-control-allow-credentials' => [Object],
'connection' => [Object],
'content-length' => [Object],
'content-type' => [Object],
'date' => [Object],
'etag' => [Object],
'keep-alive' => [Object],
'vary' => [Object],
'x-powered-by' => [Object]
},
[Symbol(headers map sorted)]: null
}
}
---------this is the error-----------
SyntaxError: Unexpected token 'o', "ok" is not valid JSON
at JSON.parse (<anonymous>)
at parseJSONFromBytes (node:internal/deps/undici/undici:6444:19)
at successSteps (node:internal/deps/undici/undici:6418:27)
at node:internal/deps/undici/undici:1133:60
at node:internal/process/task_queues:140:7
at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)Whiteleg shrimp
Depending on when you're rendering this, cookie information may not be available because it's not tied to a request. If it's dynamically rendering, then the header data should be available but if it's statically rendering then it wouldn't. It's supposed to detect what to do based on what functions you call, but I suspect that these server components are not at the top level so I'm not sure whether it will be able to detect that it should be rendered dynamically. See these docs: https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-rendering
@Wool sower gall maker Hello, can someone explain me why i cannot fetch data from my api from the server component while it works when i 'use client'? i use a cookie to validate if the user got access to my api. I just dont understand why its not working on the server side. I authenticated before so the cookie is present when i look in chrome tab application. the print statement in the server side code also shows me the exact and right cookie.
Server:
ts
import {cookies} from 'next/headers'
export default async function Menu() {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
guilds.json().then((data) => {
console.log(data);
});
const cookieStore = cookies();
const authCookie = cookieStore.get('connect.sid');
console.log(authCookie);
return <h1>Hello, Menu!</h1>
}
API:
ts
Accessing: /api/guilds
User not authenticated
Client:
ts
'use client'
import {cookies} from 'next/headers'
export default async function Menu() {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
guilds.json().then((data) => {
console.log(data);
});
const cookieStore = cookies();
const authCookie = cookieStore.get('connect.sid');
console.log(authCookie);
return <h1>Hello, Menu!</h1>
}
API:
ts
Accessing: /api/guilds
Successfully authenticated user
because cookies are being sent with the request
When you fetch on client, the cookies are set on the browser, so it send along with the request.
When you fetch on server, there is no cookies set. Instead, you should grab the cookies value and attach it to the header.
Then in your backend, check the token in cookies or headers
When you fetch on client, the cookies are set on the browser, so it send along with the request.
When you fetch on server, there is no cookies set. Instead, you should grab the cookies value and attach it to the header.
Then in your backend, check the token in cookies or headers
@Ray because cookies are being sent with the request
When you fetch on client, the cookies are set on the browser, so it send along with the request.
When you fetch on server, there is no cookies set. Instead, you should grab the cookies value and attach it to the header.
Then in your backend, check the token in cookies or headers
Wool sower gall makerOP
ah understood thanks - but why is it not possible to print this - i just disabled authentication what am I doing wrong here - sorry im just a junior
{
"msg": "WORKING"
}@Wool sower gall maker ah understood thanks - but why is it not possible to print this - i just disabled authentication what am I doing wrong here - sorry im just a junior
ts
{
"msg": "WORKING"
}
what do you mean it is not possible to print? do you mean
console.log(cookies())?Wool sower gall makerOP
i want to print the response
so that i get the msg from my api
so see if it worked
guilds.json().then((data) => {
console.log(data);
});here?
Wool sower gall makerOP
yes
gives me the json error
@Wool sower gall maker gives me the json error
try open
http://localhost:3001/api/guilds with your browserWool sower gall makerOP
its working
i get this in my chrome
{
"msg": "WORKING"
}are you fetching on client side?
Wool sower gall makerOP
no
serverside
{
"msg": "WORKING"
}this should be the server response?
Wool sower gall makerOP
yes
but it is being printed on chrome console?
Wool sower gall makerOP
its printed on the page
this doesn't look like json
could you show the code on your backend?
Wool sower gall makerOP
router.get('/', (req, res) => {
console.log("requesting guilds");
res.send({msg: "WORKING"})
});res.json({msg: "WORKING"})Wool sower gall makerOP
omg you are right thanks you
but still not working
getting the same error
what is the error
Wool sower gall makerOP
i just figuered out that the request is not happening
this is not getting printed console.log("requesting guilds"); on my backend when i access with next
@Ray what is the error
Wool sower gall makerOP
same json error
could you show the code you have now?
Wool sower gall makerOP
is it because the serverside is using a different port?
Next Code
API Code
export default async function Menu() {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
console.log(guilds);
guilds.json().then((data) => {console.log(data)});
return <h1>Hello, Menu!</h1>
}API Code
import {Router} from "express";
const router = Router();
router.get('/', (req, res) => {
console.log("requesting guilds");
res.json({msg: "WORKING"})
});
export default router;@Wool sower gall maker is it because the serverside is using a different port?
no it should be 3000
Wool sower gall makerOP
@Wool sower gall maker Click to see attachment
have you restart the express?
Wool sower gall makerOP
yes running nodemon
it still doesn't look like a valid json
restart it manually maybe
Wool sower gall makerOP
its because im not in the root folder?
im in /menu
ok go to
http://localhost:3000/menu with your browserWool sower gall makerOP
yea iam
then the error appears in my console of next
⨯ unhandledRejection: SyntaxError: Unexpected token 'o', "ok" is not valid JSON
at JSON.parse (<anonymous>)
at parseJSONFromBytes (node:internal/deps/undici/undici:6444:19)
at successSteps (node:internal/deps/undici/undici:6418:27)
at node:internal/deps/undici/undici:1133:60
at node:internal/process/task_queues:140:7
at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)@Wool sower gall maker Click to see attachment
open
https://localhost:3001/api/guilds on browserand take a screenshot
Wool sower gall makerOP
@Wool sower gall maker Click to see attachment
yes it is not a valid json still
Wool sower gall makerOP
why not
@Wool sower gall maker Click to see attachment
but this doesn't look like valid
Wool sower gall makerOP
okay what is then wrong here
router.get('/', (req, res) => {
console.log("requesting guilds");
res.json({msg: "WORKING"})
});Pollock
can u push reproducible code to a repo?
@Ray and you get error with it
Pollock
the res is valid JSON, how browser shows it can be altered via an extension or something, also the error is about JSON syntax, but it's saying "ok" is not a valid JSON, there's no "ok" in the response
like where the express defined
@Ray like where the express defined
Wool sower gall makerOP
this is the backend code
export function createApp(): Express {
const app = express();
// Enable Parsing Middleware for requests
app.use(express.json());
app.use(express.urlencoded({extended: true}));
// Enable CORS
app.use(
cors({
origin: ['http://localhost:3000'],
credentials: true
})
);
// Enable Session
app.use(session({
secret: "asdfasdfasdfasdf",
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 60 * 60 * 24 * 7 * 1000,
},
store: store.create({
mongoUrl: process.env.MONGO_DASHBOARD_URI!
})
}));
// Enable Passport
app.use(passport.initialize());
app.use(passport.session());
// Enable Routes
app.use('/api', routes);
return app;
}and basically routes its then passed by my file
so i have localhost:3001/api/guilds
@Wool sower gall maker ts
export function createApp(): Express {
const app = express();
// Enable Parsing Middleware for requests
app.use(express.json());
app.use(express.urlencoded({extended: true}));
// Enable CORS
app.use(
cors({
origin: ['http://localhost:3000'],
credentials: true
})
);
// Enable Session
app.use(session({
secret: "asdfasdfasdfasdf",
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 60 * 60 * 24 * 7 * 1000,
},
store: store.create({
mongoUrl: process.env.MONGO_DASHBOARD_URI!
})
}));
// Enable Passport
app.use(passport.initialize());
app.use(passport.session());
// Enable Routes
app.use('/api', routes);
return app;
}
do you get error if you comment out this line?
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})Wool sower gall makerOP
no the error happens here guilds.json().then((data) => {console.log(data)});
and this
guilds.json().then((data) => {
console.log(data);
});@Ray and this
ts
guilds.json().then((data) => {
console.log(data);
});
Wool sower gall makerOP
yea here it happens
try this
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
console.log(guilds)
if (guilds.ok) {
const data = await guilds.json()
console.log(data)
}Wool sower gall makerOP
export default async function Menu() {
try {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
console.log(guilds)
if (guilds.ok) {
const data = await guilds.json()
console.log(data)
}
} catch (error) {
console.error('Error fetching data:', error);
}
return <h1>Hello, Menu!</h1>
}Error fetching data: SyntaxError: Unexpected token 'o', "ok" is not valid JSON
at JSON.parse (<anonymous>)
at parseJSONFromBytes (node:internal/deps/undici/undici:6444:19)
at successSteps (node:internal/deps/undici/undici:6418:27)
at node:internal/deps/undici/undici:1133:60
at node:internal/process/task_queues:140:7
at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Pollock
const data = await guilds.text(); console.log(data);what that one shows
Wool sower gall makerOP
Error fetching data: TypeError: Body is unusable
at specConsumeBody (node:internal/deps/undici/undici:6412:15)
at Response.json (node:internal/deps/undici/undici:6315:18)
at Menu (webpack-internal:///(rsc)/./src/app/menu/page.tsx:16:39)i just dont get it when i 'use client' everything is working fine
Pollock
I have no other idea without trying it on my own
Wool sower gall makerOP
okay sorry for the circumstances
ill try to make a simple repo and push it to github
Pollock
ðŸ‘
feel free to mention me here once u have the repo, I'll try to look at it in a next free moment
Wool sower gall makerOP
yea no hurry thank you so much
@Wool sower gall maker ts
export default async function Menu() {
try {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
console.log(guilds)
if (guilds.ok) {
const data = await guilds.json()
console.log(data)
}
} catch (error) {
console.error('Error fetching data:', error);
}
return <h1>Hello, Menu!</h1>
}
Error fetching data: SyntaxError: Unexpected token 'o', "ok" is not valid JSON
at JSON.parse (<anonymous>)
at parseJSONFromBytes (node:internal/deps/undici/undici:6444:19)
at successSteps (node:internal/deps/undici/undici:6418:27)
at node:internal/deps/undici/undici:1133:60
at node:internal/process/task_queues:140:7
at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
export default async function Menu() {
try {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
console.log(await guilds.text())
} catch (error) {
console.error('Error fetching data:', error);
}
return <h1>Hello, Menu!</h1>
}try this
Wool sower gall makerOP
im getting ok
just ok two words?
Wool sower gall makerOP
just ok
check your other route on express
Wool sower gall makerOP
which one is returning
res.send("ok")Wool sower gall makerOP
well i dont know xD
i dont know why im getting ok
doesnt make sense to me when i fetch my api
i guess there must be a problem
because when i access with my browser i get this console.logs on my api
when i access via next nothing happens
yes, I think you have messed up with the route
Wool sower gall makerOP
well its not a backend problem i guess because its working when i access it via the browser
routes
import {Router} from "express";
import authRouter from "./auth";
import guildsRouter from "./guilds";
import dataRouter from "./data";
import registerRouter from "./register";
const router = Router();
router.use('/auth', authRouter);
router.use('/guilds', guildsRouter);
router.use('/data', dataRouter);
router.use('/register', registerRouter);
export default router;and guildsRouter is this
import {Router} from "express";
const router = Router();
router.get('/', (req, res) => {
console.log("requesting guilds");
res.json({msg: "WORKING"})
});
export default router;can it be that next is using the cache and not fetching it?
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include', cache: "no-store"})Wool sower gall makerOP
how can i disable it i tried restarting next but not working
Wool sower gall makerOP
HOLY ITS WOIRKINJMG
lol
Wool sower gall makerOP
wow this is weird
tho
thank you so much guys
@Wool sower gall maker Hello, can someone explain me why i cannot fetch data from my api from the server component while it works when i 'use client'? i use a cookie to validate if the user got access to my api. I just dont understand why its not working on the server side. I authenticated before so the cookie is present when i look in chrome tab application. the print statement in the server side code also shows me the exact and right cookie.
Server:
ts
import {cookies} from 'next/headers'
export default async function Menu() {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
guilds.json().then((data) => {
console.log(data);
});
const cookieStore = cookies();
const authCookie = cookieStore.get('connect.sid');
console.log(authCookie);
return <h1>Hello, Menu!</h1>
}
API:
ts
Accessing: /api/guilds
User not authenticated
Client:
ts
'use client'
import {cookies} from 'next/headers'
export default async function Menu() {
const guilds = await fetch('http://localhost:3001/api/guilds', {credentials: 'include'})
guilds.json().then((data) => {
console.log(data);
});
const cookieStore = cookies();
const authCookie = cookieStore.get('connect.sid');
console.log(authCookie);
return <h1>Hello, Menu!</h1>
}
API:
ts
Accessing: /api/guilds
Successfully authenticated user
Asian black bear
did u pass headers to fetch?:
import { headers } from 'next/headers';
...
await fetch('...', { headers: Object.entries(headers()) })Wool sower gall makerOP
â¤ï¸
Asian black bear
Oh, I'm late
@Asian black bear did u pass headers to fetch?:
js
import { headers } from 'next/headers';
...
await fetch('...', { headers: Object.entries(headers()) })
Wool sower gall makerOP
still thx geefi was a caching issue