下一个 Apollo 客户端不发送 Cookie

Posted

技术标签:

【中文标题】下一个 Apollo 客户端不发送 Cookie【英文标题】:Next Apollo Client Not Sending Cookies 【发布时间】:2021-08-25 08:14:04 【问题描述】:

所以我有一个在 localhost:5000 运行的 Express / TypeGraphql 后端和在 localhost:3000 运行的 Next / React 应用程序。我决定将 apollo-server 用于 graphql API,将 apollo-client 用于前端。成功登录后,我将 httpOnly cookie 存储在网络浏览器中。

我想要做的是,在每个请求中获取 cookie,并在 oauth2 令牌有效时授权用户。即使请求是有效的,并且我得到了查询,cookie 也显示为 null。另外,我在控制台中没有错误。

我在这里保存 cookie =>

server.ts

app.get('/auth/google/callback', function (req, res, next) 
    passport.authenticate('google',  session: false , (err, user, info) => 
        if (err) return next(err);
        if (!user) return res.redirect('/');
        res.cookie('login_cookie', JSON.stringify(info), 
            secure: false,
            httpOnly: true,
            expires: dayjs().add(30, 'days').toDate(),
            sameSite: false,
        );
        return res.redirect('http://localhost:3000/home');
    )(req, res, next);
);

在这里,我在请求后将 cookie 记录到控制台 =>

解析器.ts

@Query(() => [User])
async users(@Ctx() ctx: Context) 
    console.log('cookies ', ctx.req.cookies);
    return await ctx.prisma.user.findMany();

最后,这是我的 apollo 客户端配置 =>

apollo-client.ts

const client = new ApolloClient(
  cache: new InMemoryCache(),
  credentials: "include",
  uri: "http://localhost:5000/graphql",
);

每次请求后,我的控制台都会显示 cookies: [Object: null prototype] ,即使我在浏览器的 cookie 存储中看到它们。

request.ts

export async function getServerSideProps() 
const  data  = await client.query(
  query: gql`
    query allUsers 
      users 
        id
        username
      
    
  `,
);

return 
  props: 
    users: data.users,
  ,
;

【问题讨论】:

你是否在后端发出 GraphQL 请求,例如到服务器端呈现某些视图?我认为您必须将 cookie 转发到您的 GraphQL 后端。也许github.com/valeriangalliat/fetch-cookie 能帮上忙? 我编辑了这个问题。我这样提出请求,它也应该在我向后端发出的每个请求中自动发送 cookie。我不认为我需要一个包来做到这一点。 【参考方案1】:

我想你还没有完全理解 Next.js。 Next.js 在服务器上呈现视图,或者将“服务器端道具”发送到客户端。这意味着getServerSideProps 在服务器上执行(顾名思义)。 Cookies 是浏览器的一项功能。那么会发生什么?

    浏览器向 Next.js 发送请求。如果 Next.js 服务器和 GraphQL 服务器在同一个域中,则请求包含 Cookie 标头。 Next.js 接收请求并执行getServeSideProps。 Next.js Apollo 客户端向服务器发出请求,但缺少 cookie,因为 cookie 仅在浏览器的初始请求中!

这意味着您必须首先确保您的 Next.js 服务器从前端接收 cookie。如果它与 GraphQL 服务器位于同一来源,这应该会自动发生。否则,这有点棘手,在这种情况下使用显式 Authorization 标头应该更容易。然后,您必须通过请求传递 cookie。这可以通过访问getServerSiteProps 中的req 并使用client.query 中的context 来完成。

export async function getServerSideProps(context) 
  const Cookie = context.req.headers.cookie;
  const  data  = await client.query(
    context:  headers:  Cookie  ,
    query: gql`
      query allUsers 
        users 
          id
          username
        
      
    `,
  );

  return 
    props: 
      users: data.users,
    ,
  ;

代码未经测试,但我想你明白了。

【讨论】:

以上是关于下一个 Apollo 客户端不发送 Cookie的主要内容,如果未能解决你的问题,请参考以下文章

res.cookie 不适用于 apollo-server-express

将 JWT RefreshToken 作为 Set-Cookie 发送

如何将 cookie 添加到 vue-apollo 请求中?

Apollo Client + Next.js 不发送非 s-s-r 请求

设置 Redis cookie 时,Apollo 客户端未连接到服务器

Cookie