未在浏览器中设置会话cookie



我有一个前端客户端在自定义Next.js服务器上运行,该服务器使用apollo客户端获取数据。我的后台是graphql瑜伽和利用快速会话的prisma。

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

目前,我正在从客户端发送graphql请求,apollo客户端可以选择CCD_ 1,但也尝试过CCD_。

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

话虽如此,我也试图将apollo client的一些售后软件实现为apolloLink,它将拦截来自response.headers的cookie,但它是空的。

到目前为止,我正在考虑采用这两种途径来解决这个问题。

(我之所以实现CORS,是因为浏览器阻止在没有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中的响应中获取标头(但标头为空,之后不会提取数据):

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瑜伽,所以我需要首先从中暴露表达)

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

会话设置,存储为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
}
})
)  

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

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

这可能不是CORS问题,看起来像是第三方cookie问题。

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

假设您当前的设置如下:

frontend.com
backend.herokuapp.com

为您的后端使用自定义域,即前端的子域,可以解决您的问题:

frontend.com
api.frontend.com 

以下设置不起作用,因为herokuapp.com包含在Mozilla基金会的公共后缀列表中:

frontend.herokuapp.com
backend.herokuapp.com

更多关于Heroku的详细信息。

相关内容

  • 没有找到相关文章

最新更新