在响应标头中使用 apollo,cookie 但未设置

Posted

技术标签:

【中文标题】在响应标头中使用 apollo,cookie 但未设置【英文标题】:using apollo, cookie in response header but not being set 【发布时间】:2019-04-01 01:02:00 【问题描述】:

我正在开发一个用户登录/注册功能,作为一个更大项目的一部分,并且正在使用 localhost(apollo 服务器和 react apollo 前端)。我正在使用 express-session 进行会话。

提交登录时,我可以看到响应标头中有 set-cookie,但它没有在 Application->Cookies 中设置。

我尝试了不同的浏览器,使用 createHttpLink、apollo-boost,并使用 include & same-origin(使用 same-origin)。

我已经尝试让它工作 2 周了,但已经没有东西可以尝试了,这是我最后的选择!我知道这将是一件非常微不足道的事情,但我就是看不到。

如果我使用 GraphqL Playground 并更改设置以包含凭据,我可以看到那里设置了 cookie。

服务器在 localhost:8080/graphql 上运行 客户端在 localhost:3000 上运行

客户:

const client = new ApolloClient(
    link: new HttpLink(
        uri: 'http://localhost:8080/graphql',
        credentials: 'same-origin',
    ),
    cache: new InMemoryCache()
);

科斯:

app.use(
    cors( 
        origin: 'http://localhost:3000',
        credentials: true
    )
);

快速会话:

app.use(
    session(
        name: "sess",
        secret: process.env.SESSION_SECRET,
        resave: false,
        saveUninitialized: false,
        cookie: 
            httpOnly: true,
            secure: false,
            maxAge: 1000 * 60 * 60 * 24 * 7,
        ,
    )
);

响应 Cookie:

HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Type: application/json
Content-Length: 69
set-cookie: sess=s%3AAZXnGb5BVc1aAOwH6zBNiT8mB6Ebf75k.in%2BPU1OvxymDPdPIZBf8%2FQzrRmM0S04tXFzXDwYCnk8; Path=/; Expires=Sat, 03 Nov 2018 13:59:57 GMT; HttpOnly
Date: Sat, 27 Oct 2018 13:59:57 GMT
Connection: keep-alive

【问题讨论】:

Localhost:3000 和 localhost:8080 不是同源,因此它们不能使用凭据共享 cookie:same-origin。 当我尝试使用 include 时出现多个 CORS 策略错误:“响应中的 'Access-Control-Allow-Origin' 标头的值不能是通配符 '*' 时请求的凭据模式为“包含”。”或“预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段内容类型。” 【参考方案1】:

如果您使用的是 npm 的 cors 包,那么它会产生问题,因此请使用默认的 graphql 服务器 cros 选项,如下所示:

服务器

    await server.start()
    server.applyMiddleware(
        app, cors: 
            origin: true,
            credentials: true
        
    )

客户:

const client = new ApolloClient(
  uri: 'http://localhost:2424/graphql',
  cache: new InMemoryCache(),
  credentials: 'include'
)

【讨论】:

【参考方案2】:

我有同样的问题。如果您在 2 年后仍在寻找答案,请将客户端中的凭据设置为“包含”,如下所示:

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

【讨论】:

【参考方案3】:

我尝试通过使用 express 来修复它。但它不适用于 Apollo GraphQL。

const corsOptions = 
    origin: "http://localhost:3000",
    credentials: true
  ;
app.use(cors(corsOptions));

所以,我尝试在 GraphQL 服务器中配置 cors 并且成功了。

对于 Apollo 服务器

const corsOptions = 
    origin: "http://localhost:3000",
    credentials: true
  ;

const server = new ApolloServer(
  typeDefs,
  resolvers,
  cors: corsOptions
);

server.listen().then(( url ) => 
  console.log(`? Server ready at $url`);
);

对于 GraphQL 瑜伽

const options = 
  cors: corsOptions
;

server.start(options, () =>
  console.log("Server is running on http://localhost:4000")
);

【讨论】:

【参考方案4】:

我设法通过将 CORS 设置直接传递给 applyMiddleware 来解决这个问题。

【讨论】:

【参考方案5】:

问题似乎是 CORS 配置之一。首先,将HttpLink改成credentials: 'include';然后试试这个 CORS 中间件:

app.use(
  cors( 
    origin: 'http://localhost:3000',
    credentials: true,
    allowedHeaders: ['Content-Type', 'Authorization'],
  )
);

如果您仍然收到错误 The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.,则表明 CORS 中间件未正确设置 Access-Control-Allow-Origin: http://localhost:3000(您的示例显示它正在返回 *,但我不确定这是否是复制/粘贴问题,因为cors 模块文档建议这应该可行。)

【讨论】:

感谢您的回复,我一直收到这个:Access to fetch at 'http://localhost:8080/graphql' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

以上是关于在响应标头中使用 apollo,cookie 但未设置的主要内容,如果未能解决你的问题,请参考以下文章

Chrome 获取 Set-cookie 标头但未将其放入新请求中

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

GraphQL:无法读取 Apollo 客户端中的响应标头

apollo-client 没有响应的标头

如何从 graphQL apollo 突变或查询上的 cookie 更新授权标头

在 Apollo React 的 onError 中读取响应标头