我在一家小型咨询公司工作,我们经常为客户制作网络应用程序。Web 应用程序中经常重复编写的一部分是身份验证系统。在我们的许多网络应用程序中,我们希望支持来自各种提供商的 OAuth 登录以及基于电子邮件的注册。
但是,在每个 Web 应用程序中对此进行编程非常耗时。理想情况下,我们想要一个通用的身份验证代理服务器,它位于应用程序服务器的前面并处理与身份验证相关的所有事情(包括登录、注册和注销)。我想知道这样的事情是否安全?或者,如果有任何与安全相关的原因,为什么不应该这样做?
我想象它看起来像这样:
认证服务器
- 这基本上是一个反向代理服务器。它有自己的数据库,其中包含与身份验证相关的信息(例如,电子邮件地址、密码等)。
- 它使用会话信息检查特定 cookie 的每个请求(例如,名为 的 cookie 中的 JWT
SESSION
)。此会话信息将证明用户在过去某个时间点正确登录。如果会话信息正确,它会X-UserId
在请求中添加一个标头并将其转发给应用程序服务器。如果没有带有身份验证信息的 cookie,或者会话信息不正确,则将请求转发到不带X-UserId
标头的应用程序服务器。 - 它将具有用于登录、注销和注册的特定路由(例如,
/login
、/logout
和/register
)。它将完全自行处理这些请求。Application Server 甚至不会意识到这些请求。
应用服务器
- 这是一个普通的 Web 应用程序服务器。
- 它不执行任何身份验证,完全依赖
X-UserId
来自 Auth Server 的标头。 - 它无法从外部世界访问。访问它的唯一方法是通过 Auth Server。
- 它也有自己的数据库。它填充了与应用程序相关的所有信息(身份验证信息除外)。
以下是登录如何工作的示例,以及 Auth Server 和 Application Server 之间的交互:
以下是获取login.html
页面的步骤。
- 客户端发送请求
/login.html
。 - Auth Server 接收请求。Auth 服务器尝试查找名为
SESSION
. 它不存在,因此它将请求转发到应用程序服务器而不添加X-UserId
标头。 - 应用服务器接收请求。定义了一个路由,
/login.html
并且它不需要X-UserId
标头存在,因此它返回 HTML 为login.html
. - 身份验证服务器接收响应,并将其转发回用户。
该login.html
页面可能包含实际登录的 JS 代码。这是一种可能的方法。
- 客户端发送 AJAX 请求以
/login/email
使用电子邮件地址和密码登录。 - Auth Server 接收请求。由于这是对 Auth Server 的请求,因此它不会将请求转发到 Application Server。
- Auth Server 查看请求正文中的电子邮件地址和密码。它检查其身份验证数据库中的电子邮件地址和密码。
- 如果电子邮件地址和密码正确,它会返回一个
HttpOnly
名为的 cookieSESSION
,其中包含 JWT。
成功后,可以将用户定向到/home.html
。其步骤与 类似/login.html
,不同之处在于实际需要对用户进行身份验证:
- 用户向 发送请求
/home.html
。 - Auth Server 接收请求。Auth Server 检查
SESSION
cookie 并解码 JWT。Auth Server 根据 JWT 中的信息从数据库中获取 User Id。假设用户 ID 为 5。 - Auth Server
X-UserId=5
向请求添加一个标头并将其转发给 Application Server。(在SESSION
cookie不存在,或者JWT无法成功解码的情况下,Auth Server会在不添加X-UserId
header的情况下将请求转发给Application Server。以下步骤假设认证成功, Auth 服务器添加 `X-UserId 标头。) - 应用服务器接收请求。由于请求是 for
/home.html
,因此应用程序服务器知道需要一个有效的用户 ID,因此它会检查X-UserId
标头。 - Application Server 成功地从标头中获取 User Id,
X-UserId
并使用它从 Application DB 中提取数据并构建home.html
页面。 - Application Server 将响应与
home.html
页面一起发送到 Auth Server。 - Auth Server 接收响应,并将其转发回给用户。
以下是一些不适合上面的附加信息:
X-UserId
如果用户在将请求转发到应用程序服务器之前发送,则身份验证服务器将删除标头。- Auth Server 可能相对通用,用于多个不同的项目。Application Server 根本不必担心身份验证。
- Application Server 需要负责授权(例如,确保每个用户只能编辑自己的信息)。
- Auth Server 将完全处理新用户注册。这可能包括 OAuth 流程(用于使用由 Google、Twitter、Facebook 等提供的 OAuth),以及简单的基于电子邮件的注册。当新用户注册时,身份验证服务器将创建一个用户 ID,并将其链接到用户的电子邮件地址、谷歌用户名、Twitter 用户名等。应用程序服务器只会看到这个用户 ID(永远不会看到用户的电子邮件地址、谷歌用户名、Twitter 用户名等)。
这样的设置安全吗?