CDN上的服务器端渲染问题



我最近推出了一个使用服务器端渲染的网站(带有next.js)。该网站具有登录功能,如果用户请求中存在身份验证cookie,它将在服务器上为该用户呈现登录视图,并将呈现的登录视图返回给用户浏览器。如果用户没有身份验证cookie,那么它会在服务器上呈现一个注销视图,并将其返回给用户浏览器。

目前它工作得很好,但我在尝试通过CDN为网站提供服务时遇到了障碍。我的问题是,CDN会缓存服务器响应以加快速度,因此第一个在CDN上访问网站的用户将缓存他们的登录视图并返回到浏览器。这反过来意味着,因为它是缓存的,所以访问该网站的其他用户也会看到其他用户登录的视图,而不是他们自己的视图,因为这是CDN缓存的内容。不理想。

我正在思考解决这个问题的最佳方法是什么。我想听听关于解决这个问题最佳实践方法的建议吗?

我想到的一种方法是,在第一次访问页面时,可能总是返回一个注销的视图请求,因此身份验证/登录客户端,从那时起,总是在服务器上进行身份验证。然而,只有当next.js只在第一个请求上进行服务器端渲染,而让我们的后续请求在客户端上进行所有渲染时,这个方法才会起作用,我不确定是否是这样。

谢谢,我很乐意得到所有的帮助/建议!

更新

从我目前所能收集到的答案来看,我绕过这一问题的最佳方式似乎是在每个用户第一次访问网站时向他们提供CDN缓存的注销视图。然后,如果他们的cookie中存在身份验证令牌,我可以从前端手动登录他们。在他们登陆的第一个页面之后的所有页面都必须返回登录视图-Next.js可以这样做吗?这是个好办法吗?以下是这些步骤的摘要:

  1. 用户登录任何网页
  2. 将向服务器请求该页面以及用户cookie
  3. 因为这是他们访问的第一页,所以cookie被忽略;注销";视图返回到用户浏览器(将已缓存在CDN中)
  4. 然后前端加载一个注销的视图。加载后,它检查身份验证令牌,如果存在,则调用API将其登录
  5. 此后的任何其他页面导航都作为"导航"从服务器返回;登录";视图(即这次没有忽略身份验证cookie)。这避免了必须再次执行步骤4,这对于每个页面上的用户来说都是令人讨厌的

对于性能良好的缓存代理(您的CDN应该是这样的),您应该使用两个响应头:

缓存控制:专用

设置此响应标头意味着不允许中间代理缓存响应。(如果合适的话,浏览器仍然可以缓存它。如果你想阻止任何缓存,你可以使用no-store。)

另请参阅:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control

Vary:Cookie

此响应标头表示响应中的数据取决于Cookie请求标头。也就是说,如果我的请求具有标头Cookie: asdf,而您的请求具有标题Cookie: zxcv,则这些请求被认为是不同的,并且将被独立缓存。请注意,如果cookie用于域上的任何,则使用此响应标头可能会严重影响您的缓存。。。我敢打赌他们是。

另请参阅:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary

另一种选择

如今,一种常见的替代方法是在客户端处理所有面向用户的动态数据。这样,您可以向一些API服务器发出请求,该服务器根本没有缓存CDN。然后在客户端向页面填充所需的数据。站点的静态部分直接由CDN提供服务。

所有CDN缓存和分发数据都依赖于HTTP响应中的cache header。您应该考虑这两个简单的注意事项,以便在不错过CDN功能的情况下获得最佳性能。

1.没有用于动态内容的缓存头(HTML响应、API…):

  • 您应该确保所有动态内容(HTML响应、API…)缓存头响应都是Cache-Control: no-cache
  • 如果您正在使用next.js,可以使用自定义服务器(express.js)为您的应用程序提供服务,并完全控制响应标头,或者您可以更改next.js配置

2.为静态内容(js、CSS、images…)设置缓存头

  • 您应该确保所有静态内容(js、CSS、images…)缓存头响应都是Cache-Control: max-age=31536000
  • 如果您在每次构建中都使用next.js,那么所有资产都有一个唯一的名称,并且您可以为静态资产设置长期缓存

尝试将缓存控制标头添加到Auth所需的页面中。

缓存控制:专用

private response指令指示资源是特定于用户的——它仍然可以缓存,但只能在客户端设备上缓存。例如,标记为私有的网页响应可以由桌面浏览器缓存,但不能由内容交付网络(CDN)缓存。

我从您的问题中了解到,当用户登录时,登录视图会缓存在CDN上,当用户注销时,网站也会显示在CDN缓存的登录视图中。

这个问题的一些解决方案如下:

  1. 为CDN设置一些TTL(生存时间),以便在特定时间后自动使缓存数据无效
  2. 因为你想快速交付网站意味着你想实现低延迟。为此,您可以做一件事,只需将网站上的大文件(如图像、视频、文档等)缓存到CDN即可。不要在那里缓存整个网站。现在,每次收到用户请求时,都会从常规服务器为网站提供服务,并从CDN获取媒体文件。通过这种方式,您可以实现低延迟。随着媒体文件从CDN缓存中提取,网站代码将快速加载,网站将快速得到服务。通过这种方式,身份验证将在服务器端完成
  3. 另一种解决方案是在一段时间不活动后使cookie和身份验证无效。之后,当用户到来时,网站应该呈现一个注销的视图

最新更新