【发布时间】:2017-02-03 03:52:19
【问题描述】:
我的 Angular 2 应用(用 typescript 编码)有一个简单的身份验证方案:
- 用户登录:
- 服务器返回 JSON Web Token (JWT)
abc123... - 在每次 API 调用中,应用都会在
Authorization标头中发送 JWT - 服务器验证 JWT 并授予访问权限
现在我想添加 websockets。我想知道如何验证那里的用户。由于我无法控制将哪些标头发送到 websocket 服务器 (WS),因此我无法发送 JWT。
到目前为止我的想法(尚未实现):
- 客户端打开websocket:
let sock = new WebSocket('wss://example.com/channel/'); - WS 服务器接受握手而不进行任何身份验证检查。标准 HTTP 标头在此阶段可用。
- 客户端监听套接字上的
open事件。一旦套接字打开:- 客户端发送消息
type='auth'payload='JWT_VALUE'
- 客户端发送消息
- WS 服务器期望套接字上的第一条消息为
auth类型。一旦收到,服务器读取有效负载,验证JWT_VALUE并设置isAuthenticated标志- 如果验证失败,服务器断开套接字
- 如果没有
isAuthenticated的客户端发送任何其他类型的消息,服务器将断开套接字
2 个问题:连接但从不发送 JWT 的客户端可能会占用服务器资源,如果客户端未通过身份验证,更简洁的解决方案会阻止握手。
其他想法:
- 客户端可以在路径中发送 JWT:
new WebSocket('wss://example.com/channel/<JWT>/')- 专业人士:此信息在握手期间可用
- con:路径似乎不是 JWT 的“合适”位置。特别是因为中间代理和访问日志会保存路径;在设计 HTTP API 时,我已经决定不在 url 中包含 JWT
- 服务器可以读取客户端的 IP + UserAgent 并与发出 JWT 时由 HTTP 服务器创建的 DB 记录进行匹配。然后服务器会猜测谁在连接
- 专业人士:此信息可能在握手期间可用(不确定 IP)
- con:当客户端从一开始就没有提供 JWT 时,“猜测”客户端应该与 JWT 相关联似乎非常不安全。这意味着例如,欺骗受害者的 UA 并使用同一网络(代理、公共 wifi、大学内部网...)的人将能够冒充受害者。
如何在 websockets 上验证客户端?假设用户已经通过 HTTP 登录,并且 Angular 2 应用程序具有 JWT 令牌。
【问题讨论】:
-
我实际上实现了你的第一个想法 - 在握手后的第一条消息中发送发送 JWT 令牌。这不是一个非常干净的解决方案,但它确实有效。
标签: authentication angular typescript websocket jwt