SPA AWS Security LIVE 的身份验证和安全小指南!

2025-06-10

SPA 身份验证和安全小指南

AWS 安全上线!

这绝不是一份详尽的指南,仅供您入门。

设置:假设我们要构建一个部署到 的新 SPA 应用m.example.com,同时我们还有一个旧应用,例如 Ruby on Rails,也部署到www.example.com。新应用将是一个静态网站,例如,我们只会在其中部署资源(JS、HTML、CSS、图片)(它可能是一个带有后端和 SSR 的应用,但为了简单起见,我们先忽略这一点)。此外,我们将为api.example.comSPA 应用提供一个 API 端点。

共享会话

我们希望在新旧应用程序之间共享会话。为此,我们需要在根域中使用 Cookie - Cookie 的 HTTP 标头如下所示:

set-cookie: SID=...; Domain=.example.com

注意域名开头的点。这样,浏览器就会将 Cookie 发送到我们所有的子域名,例如m.example.comwww.example.comapi.example.com。一旦用户在我们的某个服务中通过身份验证,他们的身份验证也将在所有服务中进行。

Cookie 的安全性

所有这些考虑都是为了api.example.comwww.example.com

HttpOnly

HttpOnly指令不允许 JavaScript 访问 cookie,以防止通过 XSS 劫持会话。

set-cookie: SID=...; HttpOnly

Secure

Secure该指令指示浏览器仅通过 HTTPS 发送 Cookie,以防止通过中间人攻击劫持会话。(如果攻击者能够伪造证书,则仍然可能发起攻击)

set-cookie: SID=...;  Secure

SameSite

SameSite指令可以防止 CSRF 攻击。我选择使用这个指令的更宽松版本 ( Lax),在大多数情况下它应该足够了(请阅读说明并自行判断它是否足够)。

set-cookie: SID=...; SameSite=Lax

资产安全

所有这些 HTTP 标头都是针对m.example.com和 的www.example.com

Strict-Transport-Security

Strict-Transport-Security: max-age=86400

X-Content-Type-Options

X-Content-Type-Options: nosniff

X-Frame-Options

X-Frame-Options: DENY

X-XSS-Protection

X-XSS-Protection: 1; mode=block

Content-Security-Policy

我在这篇文章中没有用到它Content-Security-Policy,但我强烈推荐你使用它。(也许我会另写一篇文章专门介绍它)

API 安全性

跨域资源共享 (CORS)

使用CORS 。指定允许哪些方法,以及缓存预检请求的时间

access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE
access-control-max-age: 86400

指定允许访问 API 的域

access-control-allow-origin: https://m.example.com

否则allow-credentials,Cookie 将不起作用。请注意,您不能将星号 ( *) 与 credentials 指令一起使用。

access-control-allow-credentials: true

JSON API

对于所有请求(可能无需身份验证即可访问的端点除外),都需要Content-Type,这将触发 CORS 检查(通过预检请求):

Content-Type: application/json; charset=utf-8

JS 客户端

现在我们已经掌握了所有基础知识,是时候从前端实际调用 API 了。让我们使用fetchAPI来实现这一点。

匿名请求

对于允许匿名用户访问的端点,请使用“普通”获取。不要使用Content-Type,否则,它会变得更慢,并且对用户没有任何好处。

fetch(url)

经过身份验证的请求

对于其他请求,请使用credentials: "include"启用 Cookie(这是最新 Fetch 规范中的默认选项,但并非所有浏览器都实现了它)。用于headers: { "Content-Type": "application/json; charset=utf-8"}触发 CORS 检查并真正通过后端(我们之前已“实现”)的检查。

对于GET请求:

fetch(url, {
  credentials: "include",
  headers: { "Content-Type": "application/json; charset=utf-8"}
})

对于POST请求:

fetch(url, {
  credentials: "include",
  headers: { "Content-Type": "application/json; charset=utf-8"},
  method: "POST",
  body: JSON.stringify(params)
})

照片由 Tianshu Liu 在 Unsplash 上拍摄

鏂囩珷鏉ユ簮锛�https://dev.to/stereobooster/a-small-guide-to-authentication-and-security-for-spa-1am3
PREV
Dev.to 发布质量
NEXT
你什么时候成为一名开发人员?你什么时候成为一名开发人员?