Next.js在包含凭据的情况下,即使使用fetch请求,也不会发送cookies。

huangapple go评论70阅读模式
英文:

Next.js does not send cookies with fetch request even though credentials are included

问题

I'm working on a Next.js application which was originally a normal react app (created with create-react-app) and I am trying to send cookies with a fetch request to my server. However, the cookies aren't being sent even though I've set credentials: 'include' in my fetch options.

在一个Next.js应用中,我原本是一个普通的React应用(使用create-react-app创建),我尝试使用fetch请求向服务器发送cookie,但尽管我在fetch选项中设置了credentials: 'include',但cookie并没有被发送。

The exact same code is working in the "not" Next.js app.

在“非”Next.js应用中,完全相同的代码是有效的。

I also included the "use client" option. The files are in the new "app" folder from next version 13.

我还包括了“use client”选项。文件位于Next.js版本13的新“app”文件夹中。

UPDATE 1: Here is some code I used:

更新1:这是我使用的一些代码:

async function getToken() {
  const res = await fetch(
    'http://localhost:8080/api/auth/token', {
      credentials: 'include'
    }
  );
  if (!res.ok) {
    return null;
  }
  return res.json();
}

export default async function Component({
  children
}) {

  const tokenData = getToken();
  const token = await tokenData;

  /* some other code */

  return {
    children
  }
}

UPDATE 2: Based on the input from edgefish and further experimentation, I acknowledge that in versions of Next.js up to 12, methods such as getServerSideProps could be used. However, since the introduction of the "app" folder in Next.js 13, these methods no longer function within the "app" folder itself (refer to this link). I'm curious to know if there is a way to incorporate cookies into a fetch request in Next.js 13 using a server-side component. While it's possible to retrieve the client-sent cookie using the cookies method (see this link), I'm unsure how to include that cookie in the subsequent fetch request. Note that using credentials: 'include' is ineffective as long as the component is a server component.

更新2:根据edgefish的建议和进一步的实验,我承认在Next.js版本12及以前,可以使用getServerSideProps等方法。然而,自从引入了Next.js 13中的“app”文件夹后,这些方法不再在“app”文件夹本身内起作用(参考此链接)。我很好奇是否有办法在Next.js 13中使用服务器端组件将cookie纳入fetch请求中。虽然可以使用cookies方法检索客户端发送的cookie(参见此链接),但我不确定如何将该cookie包含在随后的fetch请求中。请注意,只要组件是服务器组件,使用credentials: 'include'是无效的。

英文:

I'm working on a Next.js application which was originally a normal react app (created with create-react-app) and I am trying to send cookies with a fetch request to my server. However, the cookies aren't being sent even though I've set credentials: 'include' in my fetch options.

The exact same code is working in the "not" Next js app.

I also included the "use client" option. The files are in the new "app" folder from next version 13.

UPDATE 1: Here is some code I used:

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

async function getToken() {
  const res = await fetch(
    &#39;http://localhost:8080/api/auth/token&#39;, {
      credentials: &#39;include&#39;
    }
  );
  if (!res.ok) {
    return null;
  }
  return res.json();
}

export default async function Component({
  children
}) {

  const tokenData = getToken();
  const token = await tokenData;

  /* some other code */

  return {
    children
  }
}

<!-- end snippet -->

UPDATE 2: Based on the input from edgefish and further experimentation, I acknowledge that in versions of Next.js up to 12, methods such as getServerSideProps could be used. However, since the introduction of the "app" folder in Next.js 13, these methods no longer function within the "app" folder itself (refer to this link). I'm curious to know if there is a way to incorporate cookies into a fetch request in Next.js 13 using a server-side component. While it's possible to retrieve the client-sent cookie using the cookies method (see this link), I'm unsure how to include that cookie in the subsequent fetch request. Note that using credentials: 'include' is ineffective as long as the component is a server component.

答案1

得分: 11

要在 Next 13 服务器端获取中包含 cookies:

  1. 使用 cookies 函数读取请求的 cookies。

  2. Cookie 头部添加到服务器端获取请求中:

import { cookies } from "next/headers";

async function getData() {
  const response = await fetch(process.env.API_ENDPOINT, {
    headers: { Cookie: cookies().toString() },
  });
  return await response.json();
}
英文:

To include cookies in Next 13 server-side fetch:

  1. Read the request cookies with the cookies function

  2. Add Cookie header to the server-side fetch request

import { cookies } from &quot;next/headers&quot;;

async function getData() {
  const response = await fetch(process.env.API_ENDPOINT, {
    headers: { Cookie: cookies().toString() },
  });
  return await response.json();
}

答案2

得分: 1

在 Next.js 13 中,为了授权目的,建议同时使用 SessionsCookies。仅依赖于 Cookies 是不足够的,特别是在管理服务器端进程时。

例如,考虑你正在尝试从服务器端组件获取数据,如下所示:

async function getData() {
  const response = await fetch(process.env.API_ENDPOINT, {
    headers: { Cookie: cookies().toString() },
  });
  return await response.json();
}

虽然你可以在 API_ENDPOINT 中读取 cookies,但直接在这里修改它们可能不会在客户端端反映出来。例如,如果你尝试在 API_ENDPOINT 中重新生成令牌,可以使用以下方式:

const response = NextResponse.next();
response.cookies.set({
    secure: process.env.NODE_ENV === "production",
    name: JWT_NAME,
    value: "New Token",
    httpOnly: true,
    maxAge: 5000,
    path: '/',
});
return response;

你对 cookies 所做的更改不会反映在浏览器中,因为这里的响应被发送回服务器,而不是直接发送到浏览器。

在这种情况下,像 next-auth 等库一样使用会话是有益的。

英文:

In Next.js 13, for authorization purposes, it's advised to use both Sessions and Cookies. Relying solely on Cookies is insufficient, especially when managing server-side processes.

For instance, consider you're trying to fetch data from a server-side component like this:

async function getData() {
  const response = await fetch(process.env.API_ENDPOINT, {
    headers: { Cookie: cookies().toString() },
  });
  return await response.json();
}

While you can read the cookies in the API_ENDPOINT, modifying them directly here may not reflect on the client side. As an example, if you're trying to regenerate a token in the API_ENDPOINT using:

const response = NextResponse.next();
response.cookies.set({
    secure: process.env.NODE_ENV === &quot;production&quot;,
    name: JWT_NAME,
    value: &quot;New Token&quot;,
    httpOnly: true,
    maxAge: 5000,
    path: &#39;/&#39;,
});
return response;

The changes you make to the cookies won't be reflected in the browser, because the response here is sent back to the server and not directly to the browser.

In such scenarios, it's beneficial to use sessions in the same manner as libraries like next-auth do.

答案3

得分: 0

如果你想在 nextjs 项目中发送凭证,你必须使用客户端渲染(CSR)。

import useSWR from 'swr';

const fetcher = (url: string) => fetch(url).then((res) => res.json());
const YourPage = () => {
  const { data, error, isLoading } = useSWR('https://.../data', fetcher);

   return (
     <div>{JSON.stringify(data)}</div>
   );

};

或者

如果你想使用服务器端渲染(SSR)。

你可以在 nextjs 项目中使用 getServerSideProps,像这样...

import type { GetServerSidePropsContext } from 'next';

export async function getServerSideProps(context: GetServerSidePropsContext) {
  const { cookie } = context.req.headers;

  // 从外部 API 获取数据
  const res = await fetch(`https://.../data`, {
    headers: { Cookie: cookie },
  });

  const data = await res.json();

  // 将数据传递给页面
  return { props: { data } };
}
英文:

If you wenna send credentials of fetch in nextjs project,
You must use Client-side Rendering (CSR)

import useSWR from &#39;swr&#39;;

const fetcher = (url: string) =&gt; fetch(url).then((res) =&gt; res.json());
const YourPage = () =&gt; {
  const { data, error, isLoading } = useSWR(`https://.../data`, fetcher);

   return (
     &lt;div&gt;{JSON.stringify(data)}&lt;/div&gt;
   );

};

OR

If you wenna Server-side Rendering (SSR).

You can using the getServerSideProps in nextjs project, You can like...

import type { GetServerSidePropsContext } from &#39;next&#39;;

export async function getServerSideProps(context: GetServerSidePropsContext) {
  const { cookie } = context.req.headers;

  // Fetch data from external API
  const res = await fetch(`https://.../data`, {
    headers: { Cookie: cookie },
  });

  const data = await res.json();

  // Pass data to the page
  return { props: { data } };
}

huangapple
  • 本文由 发表于 2023年5月18日 01:02:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76274546.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定