下一个 Apollo 客户端不发送 Cookie

时间:2021-06-08 09:46:22

标签: javascript cookies graphql apollo-client

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

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

我在这里保存 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 记录到控制台 =>

resolver.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,
  },
};

}

1 个答案:

答案 0 :(得分:1)

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

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

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

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,
    },
  };
}

代码未经测试,但我认为您明白了。

相关问题