1

我有多个客户端从应用程序连接到 Node.js TCP 套接字服务器。我想知道一种管理他们会话的安全方式。

用户名 + 密码通过套接字传递到服务器。服务器确认这是正确的。

我相信我现在需要生成一个唯一的令牌以发送回客户端。

现在,如果用户关闭应用程序,然后再次打开它,此令牌可以传递给服务器,因此服务器将确认用户再次通过身份验证。

但是,其他人可能会使用此令牌来访问此人的帐户。有没有办法防止这种情况?

是否有更安全的方法(同时仍保持用户无需再次登录即可进行身份验证的能力)?

您将如何使用相同的登录名处理来自其他设备的连接。他们得到不同的令牌还是相同的令牌?

非常感谢。

4

3 回答 3

4

这取决于您对足够安全的定义。您现在正在做的事情,本质上是会话跟踪,并且对于许多通用用途而言通常足够安全 - 但是通常会添加一个额外的组件,其中会话应仅被视为对特定 IP 有效。如果用户的 IP 发生变化,你应该让他们重新登录并给他们一个新的令牌。这样,如果一些坏人劫持了他们的会话 ID,那对他们没有任何好处。

当然,这仅在您的坏人无法与您的客户端来自同一 IP 地址时才有效。如果您担心与您的客户端位于同一 NAT 后面的坏人,因此可能看起来来自同一 IP,那么您将不得不进一步提高安全性,并且可能考虑使用类似于 SSH 的系统用途,但这有点复杂。

至于来自多个设备的连接,这取决于您 - 您可以跟踪某个令牌并在用户从不同 IP 登录时交回该令牌(同时现在允许两个 IP 访问该站点使用相同的令牌),或者您可以在每次有人进行身份验证时发出一个新的令牌。就我个人而言,我倾向于发现发行新令牌更容易,更少跟踪和麻烦......但这取决于您的应用程序以及您想要如何组织事物,我可以为这两种方法设计好的用例。


另外,至于进行密码交换..您至少应该在那里进行一些哈希处理,即服务器向客户端发送 some random_string,然后客户端使用某些hash函数(例如md5or sha)进行计算hash(random_string + hash(username + password))并将其发送回。hash(random_string + password_hash)然后,服务器通过检查是否等于用户发送的任何内容来验证此匹配。这使得用户的纯文本密码永远不必存储在任何地方 - 在password_hash = hash(username+password)密码更改时您只需存储的服务器上。

于 2013-01-09T21:58:15.680 回答
1

也许是这样的:

FIRST LOGIN:
username + pwd (hashed)       ---> check user/hashed pwd
receive token                 <--- send token 

NEXT LOGIN:
request login                 ---> receive request 
receive random string         <--- send random string
hash string with token as salt ---> compare hashed string

您应该只允许使用该随机字符串进行一次尝试,如果可能,请检查原始登录的 IP。

这并不完美,因为您仍然可以在登录时拦截令牌,但是您还将拥有用户名和密码。

于 2013-01-06T19:26:52.673 回答
0

这个问题基本上归结为使用被盗 cookie 进行的会话劫持。所以问题是如何尽可能地保护 cookie。

  1. 使用 https 而不是 http并强制您的用户使用 https。这样,cookie 就不会以明文形式传输,也不会被窃听。

  2. 在 cookie 上设置secure属性(参见Wikipedia)以将 cookie 绑定到 https 并避免它通过 http 传输。

  3. 使用某种消息身份验证摘要,例如 HMAC,以确保 cookie 没有被篡改。

  4. 或者,您可以将客户端的 IP 地址嵌入到 cookie 中,并且仅在从特定 IP 发送时才接受它。不幸的是,这可能会导致代理服务器或不时重新分配 IP 地址的拨号连接出现问题。

  5. 最后但并非最不重要的一点是,允许一个令牌在给定时间点仅使用一次。如果用户在第二台机器上使用相同的令牌登录,则要么禁止连接,要么结束第一台机器的会话。

希望这可以帮助 ...

PS:非常抱歉,我跳过了TCP部分。当然我写的大部分内容只适用于http,而不适用于TCP。无论如何,有些事情可能会有所帮助,例如#3、#4 和#5。

于 2013-01-03T18:55:00.747 回答