我知道这可能看起来像一个琐碎的问题,但我找不到答案,至少能让我心安。
如果一个移动应用正在与服务器通信,通常他们会登录并获得一个访问令牌,可以在整个会话中用于任何未来请求。
为什么不直接通过每个请求的HTTPS传递用户名和密码,而不是使用访问令牌。访问令牌需要与数据库进行验证,用户名/密码的组合也是如此。为什么要额外付出获取访问令牌的努力,如果它们发挥相同的作用?我知道我遗漏了什么,但我无法弄清楚。
我知道这可能看起来像一个琐碎的问题,但我找不到答案,至少能让我心安。
如果一个移动应用正在与服务器通信,通常他们会登录并获得一个访问令牌,可以在整个会话中用于任何未来请求。
为什么不直接通过每个请求的HTTPS传递用户名和密码,而不是使用访问令牌。访问令牌需要与数据库进行验证,用户名/密码的组合也是如此。为什么要额外付出获取访问令牌的努力,如果它们发挥相同的作用?我知道我遗漏了什么,但我无法弄清楚。
你说得没错,访问令牌的验证方式与用户名和密码基本相同。在访问令牌有效期内,它基本上等同于用户名和密码。在某些情况下(取决于你的威胁模型),甚至可以在每个请求中发送用户名和密码,也许不适用于移动应用程序,但例如在服务器之间的请求中,需要适当的控制。
然而,你不希望从移动应用程序的每个请求中发送密码,因为那样就必须存储密码。
密码(或实际上是用户)的问题在于它们被重用。密码是有价值的目标,因为同一个密码可能在多个服务中使用。因此,你将其交换为寿命较短的访问令牌,如果被窃取,则对用户的风险更小。而且,你无法轻松地撤销密码,强制用户更改密码会很麻烦。撤销访问令牌很容易。
虽然可能性非常小,但有时TLS存在漏洞——虽然不是很频繁,但在过去几年中确实出现了一些漏洞。这种漏洞可能允许攻击者解密 https 发送的一些流量,或者例如一段时间前 openSSL 中出现了一个漏洞,允许攻击者提取服务器内存的部分,潜在地持有用户发送的任何内容。如果仅使用访问令牌而不是实际密码,则效果要好得多。
另一个要点是,在某些情况下(在 OAuth 流程中),你的应用程序甚至不被允许访问实际密码。当用户使用第三方身份提供者(例如 Facebook)登录时,他们不希望你的应用程序接收他们的 Facebook 密码。他们只需前往 Facebook,交换他们的凭据以获取访问令牌,你只能看到该令牌,如果你需要可以与 Facebook 进行验证。但你实际上永远不会获得用户的 Facebook 密码。当然,这仅适用于身份提供者是第三方的情况。
我认为答案与安全有关。
建议始终使用访问令牌而非用户名和密码,因为:
访问令牌(在大多数服务中)可以轻松生成、阻止、监视其使用和统计信息,可以设置过期时间、受限权限等等……当然,您也可以完全删除它。用户名和密码是主人,可以控制访问令牌。
正如我所说,访问令牌更加安全,这是最重要的。如果您在网络应用程序(或其他任何地方)中使用用户名和密码,并且该应用程序被黑客攻击(这种情况经常发生),或者有人查看其源代码,甚至某些日志系统保存请求参数-那么您的用户和密码可能会被第三方查看,您的整个帐户可能会被黑客攻击(并且可能还有其他帐户共用相同的用户名和密码)。访问令牌消除了所有这些风险。
关于速度-我不认为使用用户和密码进行授权具有任何显着优势。