的情况
- 我正在编写一个单页Web应用程序(使用Angular(。让我们称之为SPA
- 另一个团队成员正在编写一些API(使用Node.js(
- 我的SPA是使用Login/passwd登录到服务器,并做一些事情
我的队友决定使用cookie来跟踪会话。因此,成功登录后,将在加载SPA的web浏览器中设置仅http cookie。
问题
如果我们把SPA放在服务器的public_html目录中,一切都会很好。然而,这使得SPA成为API代码的一部分。这打破了我们的构建过程,因为现在SPA的每个版本升级都需要升级API。
如果我们在一个单独的Web服务器中托管SPA,该服务器只提供静态SPA文件,我会遇到CORS问题。由于SPA与它试图访问的API来自不同的来源,浏览器会阻止ajax调用。为了克服这个问题,我们必须在服务器端适当地设置Access-Control-Allow-Origin
。我也知道需要设置Access-Control-Allow-Credentials:true
,以指示浏览器设置/发送cookie。
可能的解决方案
-
我们创建了一个构建过程,每当SPA升级时,该过程都会对服务器的public_html目录进行git拉取。我正在努力避免这种情况,以便将客户端和服务器升级分开。
-
我们创建了一种代理类型的情况,其中服务器不存储SPA文件,而是从托管SPA文件的另一台服务器按需收集这些文件。在这种情况下,web浏览器将看到来自同一来源的SPA文件和随后的ajax调用。
-
我们对服务器进行编码,以便在其响应中设置
Access-Control-Allow-Origin:*
。首先,这太开放了,看起来不安全<这真的没有安全感吗,还是只是我的感觉>此外,由于我们正在设置Access-Control-Allow-Credentials:true
,Chrome会抱怨Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.
。为了克服这一点,我们必须在Access-Control-Allow-Origin
中放置确切的原点(可能使用正则表达式(。这可能会严重限制我们向未知域中的用户分发SPA。 -
对于服务器API设计器,基于Cookie的身份验证是否是推荐的处理SPAs身份验证的方法?基于OAuth2.0和JWT的身份验证似乎表明基于Cookie的身份验证不适合SPAs。有什么优点/缺点吗?
请对以上选项发表评论,或建议您可能使用过的任何其他选项。提前谢谢。
我认为问题在于您的术语令人困惑。API不是server
,它是一个应用程序,它生活在一台也可以是server
的机器上。如果你做一个NodeJS API,我建议你在它之前使用Nginx服务器作为反向代理。假设你希望Nginx server、API和SPA文件都在同一台机器上,你可以将API部署到一个目录,将SPA部署到另一个目录并让Nginx相应地路由请求。
所以我相信解决方案2是可行的。从那里,您可以通过增加实例数量(如果您使用AWS(来轻松扩展,并对它们进行负载平衡,或者将API分离到自己的应用程序服务器中。
至于身份验证。对于SPA或API请求,我一直更喜欢使用带有访问令牌的头授权,而不是Cookie。虽然您可以通过本地存储保存访问令牌,但每个请求都是自包含的,不需要在浏览器上保存持久字符串,这一想法对我更具吸引力。
我会选择解决方案2或3。
2:您可以在同一台服务器上设置(网页和API((或使用反向代理(,以便从外部角度来看,它们共享相同的来源。
3:在API的情况下,同源策略变得不那么重要。API将由不属于您的web应用程序的客户端使用,不是吗?我认为设置一个更宽松的allow-origin标头不会有任何问题。我所说的"更宽松"并不是指通配符,只需添加网页的来源即可。为什么要使用通配符?