gpt4 book ai didi

heroku - 浏览器中未设置 session cookie

转载 作者:行者123 更新时间:2023-12-03 17:14:23 25 4
gpt4 key购买 nike

我在自定义 Next.js 服务器上运行前端客户端,该服务器使用 apollo 客户端获取数据。
我的后端是带有 prisma 的 graphql-yoga,它使用了 express-session。

我在为我的客户端和后端选择正确的 CORS 设置时遇到问题,因此 cookie 将在浏览器中正确设置,尤其是在 heroku 上。

目前我正在使用 apollo-client 选项从客户端发送 graphql 请求credentials: "include"但也试过"same-origin"没有更好的结果。

我可以在 Set-Cookie 中看到来自后端的 cookie 客户端响应。 header ,并在 devTools/application/cookies 中。但是这个 cookie 对浏览器是透明的,并且在刷新时会丢失。

话虽如此,我还尝试对 apollo client 实现一些后件。如apolloLink这将拦截来自 response.headers 的 cookie但它是空的。

到目前为止,我正在考虑寻求这两种解决问题的途径。

(我只实现 CORS,因为浏览器阻止在没有它的情况下获取数据。)

客户

客户端的 ApolloClient 配置:

const httpLink = new HttpLink({
credentials: "include",
uri: BACKEND_ENDPOINT,
});

客户端 CORS 使用和配置:
 app
.prepare()
.then(() => {
const server = express()
.use(cors(corsOptions))
.options("*", cors(corsOptions))
.set("trust proxy", 1);

...here goes rest of implementation

const corsOptions = {
origin: [process.env.BACKEND_ENDPOINT, process.env.HEROKU_CORS_URL],
credentials: true,
allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With", "X-Forwarded-Proto", "Cookie", "Set-Cookie", '*'],
methods: "GET,POST",
optionsSuccessStatus: 200
};

我尝试从 apolloClient 的响应中获取 header (但 header 为空,之后未获取数据):
const middlewareLink = new ApolloLink((operation, forward) => {
return forward(operation).map(response => {
const context = operation.getContext();

const {response: {headers}} = context;
if (headers) {
const cookie = response.headers.get("set-cookie");
if (cookie) {
//set cookie here
}
}
return response;
});

});

后端

CORS 实现(请记住,这是 gql-yoga,所以我需要首先从中公开 express)
server.express
.use(cors(corsOptions))
.options("*", cors())
.set("trust proxy", 1);

...here goes rest of implementation
const corsOptions = {
origin: [process.env.CLIENT_URL_DEV, process.env.CLIENT_URL_PROD, process.env.HEROKU_CORS_URL],
credentials: true,
allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With", "X-Forwarded-Proto", "Cookie", "Set-Cookie"],
exposedHeaders: ["Content-Type", "Authorization", "X-Requested-With", "X-Forwarded-Proto", "Cookie", "Set-Cookie"],
methods: "GET,HEAD,PUT,PATCH,POST,OPTIONS",
optionsSuccessStatus: 200
};

session 设置,存储为 connect-redis
server.express
.use(
session({
store: store,
genid: () => uuidv4(v4options),
name: process.env.SESSION_NAME,
secret: process.env.SESSION_SECRET,
resave: true,
rolling: true,
saveUninitialized: false,
sameSite: false,
proxy: STAGE,
unset: "destroy",
cookie: {
httpOnly: true,
path: "/",
secure: STAGE,
maxAge: STAGE ? TTL_PROD : TTL_DEV
}
})
)

我希望在身份验证后在客户端上设置 session cookie。

实际结果:
Cookie 仅在 Set-Cookie 响应 header 中可见,但对浏览器是透明的,既不持久也不设置(在刷新或页面更改时丢失)。有趣的是,我仍然可以对数据发出经过身份验证的请求。

最佳答案

这可能不是 CORS 问题,它看起来像第三方 cookie 问题。
不同浏览器的行为可能会有所不同,所以我建议测试几个。 Firefox(从 77 版开始)似乎限制较少。在 Chrome(从版本 83 开始)中,当第三方 cookie 被阻止时,URL 栏的最右侧有一个指示符。您可以通过为当前网站创建异常(exception)来确认第三方 cookie 是否是问题的原因。
假设您当前的设置如下:

frontend.com
backend.herokuapp.com
使用作为前端子域的后端自定义域可以解决您的问题:
frontend.com
api.frontend.com
以下设置将不起作用,因为 herokuapp.com包含在 Mozilla 基金会的公共(public)后缀列表中:
frontend.herokuapp.com
backend.herokuapp.com
More details on Heroku .

关于heroku - 浏览器中未设置 session cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54188543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com