简体   繁体   English

验证 WebSocket 连接

[英]Authenticating WebSocket Connections

This may seem like a pretty noobish question, but I just recently got into Node.js and am needed to make sure that the same kind of Authentication that occurs in my Laravel App happens in Node.js.这似乎是一个非常愚蠢的问题,但我最近才进入 Node.js,需要确保在我的 Laravel 应用程序中发生的相同类型的身份验证发生在 Node.js 中。

Clearly, I need to use an API, but I am confused about how to do it in a manner that is secure.显然,我需要使用 API,但我对如何以安全的方式使用 API 感到困惑。 I have looked into this article:我查看了这篇文章:

https://www.ida.liu.se/~TDP024/labs/hmacarticle.pdf https://www.ida.liu.se/~TDP024/labs/hmacarticle.pdf

And have looked through their algorithm into building an API.并研究了他们的算法来构建 API。 But I do not understand how it would be secure.但我不明白它会如何安全。

According to the post, you store a public and private key in a Database.根据帖子,您将公钥和私钥存储在数据库中。 The public key can be seen by everyone but the private key is, well, private.每个人都可以看到公钥,但私钥是私人的。 However, when sending it to the server, you send a hashed version along with other data, of the private to the server.但是,当将它发送到服务器时,您将散列版本与其他数据一起发送给服务器。

This sounds all well and fine.这听起来不错。 However, does that not mean that the public key and the hash is public, thus the private key is exposed as well?但是,这是否意味着公钥和哈希是公开的,因此私钥也暴露了?

For example lets say I try to establish the following connection例如,假设我尝试建立以下连接

ws://example.com/pull?public=A89-3NJ2-KAN-NKSN1&hash=QmFzZTY0IHRoZSBoZWxsIG91dCBvZiBtZSBiYWJ5Li4uLi4u

What stops another user from just sharing this link giving an unrelated user access to it?是什么阻止其他用户只共享此链接,让不相关的用户访问它?

The article you linked to describes how to authenticate one single request , not an entire session.您链接到的文章描述了如何验证单个请求,而不是整个会话。 That is, the user sends the public api_key along with some request data that describes the specific request for the API (like, { "action":"latest_price", "symbol":"GOOG"} for a stock market API).也就是说,用户将公开的api_key与一些描述 API 特定请求的request数据一起发送(例如, { "action":"latest_price", "symbol":"GOOG"}用于股票市场 API)。

To authenticate, the user also uses a shared API-access secret key as an HMAC key to compute HMAC(secret, api_key+request) .为了进行身份验证,用户使用共享的 API 访问密钥作为HMAC密钥来计算HMAC(secret, api_key+request) No one else can compute this if they don't know the secret .如果他们不知道这个secret就没有其他人可以计算出这一点。 Only the user and the server should know secret , because it's basically the user's password to use the API.只有用户和服务器应该知道secret ,因为它基本上是使用 API 的用户密码。

The situation you describe is very different: you're using a WebSocket, so I assume you'll be sending requests interactively.您描述的情况非常不同:您使用的是 WebSocket,因此我假设您将以交互方式发送请求。 If you want to authenticate the entire socket session, this approach doesn't make sense, since it's designed to authenticate a single request.如果您想对整个套接字会话进行身份验证,这种方法没有意义,因为它旨在对单个请求进行身份验证。 You can apply this approach to individual requests inside the WebSocket connection.您可以将此方法应用于 WebSocket 连接的单个请求。

For authenticating a new connection (ie, "what logged-in user is opening this connection?") using auth cookies is appropriate, just as you would for a traditional HTTP connection.使用 auth cookie 对新连接进行身份验证(即“哪个登录用户正在打开此连接?”)是合适的,就像您对传统 HTTP 连接所做的那样。


Below, I'll assume that the purpose of the Web Socket is to send only one request (which really makes me wonder why it's a WebSocket), so that the request-level authentication makes sense.下面,我将假设 Web Socket 的目的仅发送一个请求(这真的让我想知道为什么它是 WebSocket),这样请求级身份验证才有意义。

What stops another user from just sharing this link giving an unrelated user access to it?是什么阻止其他用户只共享此链接,让不相关的用户访问它?

Nothing.没什么。 Do you want someone else to submit a specifc request, while impersonating you?您是否希望其他人在冒充您的同时提交特定请求? Then by all means, give them that link and tell them to use it.然后无论如何,给他们那个链接并告诉他们使用它。

The credentials in the link include an HMAC of the API request (plus your identity) that only you can generate, as the sole owner on your API secret key.链接中的凭证包括 API 请求的 HMAC(加上您的身份),只有您作为 API 密钥的唯一所有者才能生成。 If you give that HMAC to someone else, they can submit it and impersonate you for that specific request.如果您将该 HMAC 提供给其他人,他们可以提交该 HMAC 并针对该特定请求冒充您。 However, they cannot create more requests, because they don't have your API secret to make more HMAC values for different requests.但是,它们无法创建更多请求,因为它们没有您的 API 密钥来为不同的请求生成更多 HMAC 值。

In fact, if you didn't want that request to be submitted, you should not have used your secret to create the authenticating HMAC in the first place!事实上,如果您不想提交该请求,那么您首先不应该使用您的秘密来创建身份验证 HMAC! Why did your authenticate a request that you didn't intend to be submitted?为什么要验证您不打算提交的请求?

Have a look at this看看 这个

Essentially本质上

  1. make a "websocket preauth" request to the backend from the browser using the site's normal auth使用站点的正常身份验证从浏览器向后端发出“websocket preauth”请求
  2. backend returns a CSRF token in the response body and sets a "websocket auth" cookie with SameSite=Strict in the response headers后端在响应正文中返回 CSRF 令牌,并在响应标头中使用SameSite=Strict设置“websocket auth”cookie
  3. attempt to establish a websocket connection with the backend, with the addition of the CSRF token in a query parameter尝试与后端建立 websocket 连接,并在查询参数中添加 CSRF 令牌
  4. the backend checks后端检查
    • that the websocket auth cookie and CSRF token are valid websocket auth cookie 和 CSRF 令牌是有效的
    • that the value of the Origin header matches an approved domain Origin标头的值与批准的域匹配
  5. the backend sends a response and upgrades the connection to use websockets后端发送响应并升级连接以使用 websockets

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM