paw*_*icz 5 heroku cross-domain session-cookies next.js apollo-client
我在自定义 Next.js 服务器上运行前端客户端,该服务器使用 apollo 客户端获取数据。我的后端是使用 express-session 的带有棱镜的 graphql-yoga。
我在为我的客户端和后端选择正确的 CORS 设置时遇到问题,因此可以在浏览器中正确设置 cookie,尤其是在 heroku 上。
目前我正在从客户端发送 graphql 请求,apollo-client 有选项,
credentials: "include"但也尝试"same-origin"过没有更好的结果。
我可以在Set-Cookie标头和 devTools/application/cookies 中看到后端响应的 cookie 客户端。但是这个 cookie 对浏览器是透明的,刷新时会丢失。
话虽如此,我还尝试实施一些后件,apollo client因为apolloLink这会拦截 cookie,response.headers但它是空的。
到目前为止,我正在考虑采用这两种解决问题的途径。
(我只是在实现 CORS,因为浏览器会阻止在没有它的情况下获取数据。)
客户
客户端的 ApolloClient 配置:
const httpLink = new HttpLink({
credentials: "include",
uri: BACKEND_ENDPOINT,
});
Run Code Online (Sandbox Code Playgroud)
客户端 CORS 使用和配置:
app
.prepare()
.then(() => {
const server = express()
.use(cors(corsOptions))
.options("*", cors(corsOptions))
.set("trust proxy", 1);
...here goes rest of implementation
Run Code Online (Sandbox Code Playgroud)
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
};
Run Code Online (Sandbox Code Playgroud)
我试图从 apolloClient 中的响应中获取标头(但标头为空,之后未获取数据):
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;
});
});
Run Code Online (Sandbox Code Playgroud)
后端
CORS 实现(记住那是 gql-yoga 所以我需要首先从中公开表达)
server.express
.use(cors(corsOptions))
.options("*", cors())
.set("trust proxy", 1);
...here goes rest of implementation
Run Code Online (Sandbox Code Playgroud)
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
};
Run Code Online (Sandbox Code Playgroud)
会话设置,存储是 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
}
})
)
Run Code Online (Sandbox Code Playgroud)
我希望在身份验证后在客户端上设置会话 cookie。
实际结果:Cookie 仅在 Set-Cookie 响应标头中可见,但对浏览器是透明的,并且不持久也不设置(在刷新或页面更改时丢失)。有趣的是,我仍然可以对数据发出经过身份验证的请求。
这可能不是 CORS 问题,看起来像是第三方 cookie 问题。
\n不同浏览器的行为可能有所不同,因此我建议测试多个浏览器。Firefox(自版本 77 起)似乎限制较少。在 Chrome(自版本 83 起)中,当第三方 cookie 被阻止时,URL 栏最右侧会有一个指示器。您可以通过为当前网站创建例外来确认是否是第三方cookies导致了问题。
\n假设您当前的设置如下:
\nfrontend.com\nbackend.herokuapp.com\nRun Code Online (Sandbox Code Playgroud)\n为后端使用作为前端子域的自定义域可以解决您的问题:
\nfrontend.com\napi.frontend.com \nRun Code Online (Sandbox Code Playgroud)\n以下设置不起作用,因为herokuapp.com它包含在 Mozilla Foundation\xe2\x80\x99s\xc2\xa0公共后缀列表中:
frontend.herokuapp.com\nbackend.herokuapp.com\nRun Code Online (Sandbox Code Playgroud)\n\n
| 归档时间: |
|
| 查看次数: |
1467 次 |
| 最近记录: |