我有多个客户端从应用程序连接到Node.js TCP套接字服务器。我想知道一种管理会话的安全方法。
用户名+密码通过套接字传递给服务器。服务器确认这是正确的。
我相信我现在需要生成一个唯一的令牌以发送回客户端。
现在,如果用户关闭应用程序,然后再次打开它,则此令牌可以传递到服务器,因此服务器将确认用户再次进行身份验证。
但是,可能有其他人可以使用此令牌来访问此人帐户。有办法防止这种情况吗?
是否有更安全的方式(同时仍然保持用户无需再次登录即可进行身份验证的能力)?
您将如何使用相同的登录处理来自其他设备的连接。他们是否获得了不同的令牌或相同的令牌?
非常感谢。
答案 0 :(得分:4)
归结为你对安全的定义。您现在正在做什么,实际上是会话跟踪,并且它通常足够安全用于许多通用用途 - 但是通常会添加一个额外的组件,其中会话应该仅被视为对特定IP有效。如果用户的IP发生更改,您应该再次登录并向他们发送新令牌。这样一来,如果一些坏人劫持了他们的会话ID,那就不会对他们造成任何好处。
当然,这只有在您的坏人看起来不像您的客户端来自同一IP地址时才有效。如果你担心与你的客户在同一个NAT背后的坏人,因此看起来似乎来自同一个IP,那么你将不得不提高你的安全性,并考虑一个类似于SSH的系统使用,但这有点复杂。
对于来自多个设备的连接,由您决定 - 您可以跟踪某个单一令牌,只需在用户从其他IP登录时回拨该令牌(同时现在同时允许两个IP)使用相同的令牌访问网站),或者您可以在每次有人进行身份验证时发出新的令牌。就个人而言,我倾向于发现更容易发布新鲜令牌,更不用说跟踪和麻烦......但是它归结为你的应用程序以及你想如何组织事物,我可以为这两种方法设想好用例。
另外,至于进行密码交换..你至少应该在那里进行一些散列,即服务器向客户端发送一些random_string
,然后客户端使用一些hash
函数(例如{{1} }}或md5
)来计算sha
并将其发回。然后,服务器通过检查hash(random_string + hash(username + password))
等于用户发送的任何内容来验证此匹配。这使得用户的纯文本密码永远不必存储在任何地方 - 在密码更改时只存储hash(random_string + password_hash)
的服务器上。
答案 1 :(得分: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。
这并不完美,因为您仍然可以在登录时截取令牌,但之后您还会拥有用户名和密码。
答案 2 :(得分:0)
这个问题基本上归结为使用被盗cookie进行会话劫持。所以问题是如何尽可能好地保护cookie。
使用https代替http 并强制用户使用https 。这样,cookie不会以明文形式传输,也不会被窃听窃取。
在Cookie上设置secure
属性(请参阅Wikipedia),将Cookie绑定到https,避免通过http传输。
使用某种消息身份验证摘要(例如HMAC)来确保cookie没有被篡改。
您可以选择将客户端的IP地址嵌入到cookie中,只有在从特定IP发送时才接受它。不幸的是,这可能会导致代理服务器或拨号连接出现问题,其中IP地址是不时重新分配的。
最后但并非最不重要的是,只允许一个令牌在给定时间点使用一次。如果用户在第二台计算机上使用相同的令牌登录,则禁止连接或结束第一台计算机的会话。
希望这会有所帮助......
PS:我很抱歉,我跳过 TCP 部分。当然,我写的大部分内容仅适用于http,而不是TCP。无论如何,有些事情可能会有所帮助,例如#3,#4和#5。