我会说你几乎做对了:D以下是我在应用程序中处理登录/注销的方法:
- 用户加载页面 - 如果他设置了带有令牌的cookie(有关详细信息,请参阅下一点),请将该令牌发送到服务器以检查它是否仍然有效。如果有效,则表示您已登录,请转到第 5 点。请参阅下面有关如何处理无效令牌的说明。
- 用户输入用户/通道组合。此信息被发送到服务器(最好通过加密连接发送它,但使用GWT很难实现 - 例如,请参阅此问题)。
- 服务器检查用户/密码哈希(见下文)组合是否与数据库中的内容/任何内容匹配。如果是这样,它会生成一个令牌(只是一些随机的,相当长的字符串,如UUID)并将其发送回客户端。
- 如果用户在登录时选中了“记住我”复选框,请将令牌存储在具有未来到期日期的cookie中(请参阅有关建议时间段的其他指南/问题)。
- 当客户端收到令牌时,它应将其用于对服务器发出的每个请求,而您希望只有经过身份验证的用户才能执行这些请求。在那里,服务器检查令牌是否有效(您必须跟踪数据库中的令牌/用户对),如果是,则授权交易/任何内容。问题是:如果您仅依赖cookie,您将容易受到XSRF攻击。这就是为什么你也应该传递令牌(cookie是自动传输的 - 这就是为什么XSRF攻击是可能的)作为请求的一部分(你知道,就像JSON中的附加字段或你通过GWT-RPC甚至HTTP标头发送的POJO中的字段一样)。
-
在显式注销(单击“注销”链接等)时,向服务器发送此用户刚刚注销的信息。然后,服务器应删除/使令牌失效。无论“记住我”选项如何,它都应该这样做 - 因为显式注销意味着用户想要删除该PC /浏览器上的登录信息并阻止其他人以他/她的身份登录。如果用户刚刚关闭浏览器/页面,并且您在第4点中正确设置了cookie(这意味着,它不会在浏览器关闭时过期 - 再次,仅当选择了“记住我”选项时),则在下次访问时,用户应该自动登录到第1点。
一些额外的注意事项
-
这一点非常重要:请记住在服务器端检查通过cookie传递的令牌是否等于作为请求/有效负载的一部分传递的令牌。
-
不要将密码以纯文本形式存储在数据库中 - 存储密码的哈希值。使用 BCrypt 获得最大的安全性。这就是为什么我写你应该比较密码哈希,而不是实际的密码。
-
当服务器遇到无效令牌时,这可能意味着许多事情 - 从正常到警报。通常,最好记录这些情况并定期检查日志中是否有任何异常活动。
- 用户有一段时间没有访问该网站,令牌已过期。确保在客户端正确处理令牌过期(Cookie 上正确的过期日期应导致用户重定向到登录页面,而不发送过期的令牌)和服务器端(每天扫描令牌列表并删除过期令牌的特殊任务?
- 也许您已经对令牌验证施加了一些其他限制 - 例如令牌不能过期,并且当前尝试必须来自与最初生成令牌的IP相同的IP。
- 发送请求时出错,并且格式不正确/损坏 - 对此无能为力,但将用户重定向到登录页面
-
第三方正在尝试使用手工制作的令牌登录。如果你使用愚蠢容易猜到的令牌(比如基于用户名,rot13,自己的超级特别的“加密”等),那么你迟早会被这个咬伤。UUID是一个很好的令牌候选示例 - 顾名思义,它是一个通用的唯一标识符 - 这意味着没有两个用户应该具有相同的UUID,并且UUID本身是随机和长的。
AJAX应用程序中的安全性是一项严肃的业务 - 我见过太多的Web应用程序具有易于利用的安全漏洞...确保你完全理解你在做什么以及为什么。如果您有任何疑问,请随时询问:)
2015 年 6 月 12 日更新:GWT - 安全性 RPC XSRF