我尝试了不同的身份验证方式,但是仍然存在一些误解,因此我需要经验丰富的人的建议。
让我告诉我我如何理解所有这些东西。如果我理解不正确,请告诉我。
就REST API和Web而言,它都是无状态的,我们需要在每个请求中发送一些auth数据(cookie,令牌...)。我知道三种使用HTTPS对用户
令牌进行身份验证的机制。我已经使用这种方法很多次,对于HTTPS来说已经足够了。如果用户提供正确的密码和登录名,他将收到令牌作为响应,并将其用于其他请求。令牌由服务器生成并存储,例如存储在单独的表中或存储用户信息的表中。因此,对于每个请求服务器,请检查用户是否具有令牌,并且该令牌与数据库中的令牌相同。一切都非常简单。
JWT令牌。该令牌是自描述的,它包含有关令牌本身的所有必要信息,用户不能更改例如到期日期或任何其他声明,因为该令牌是由服务器使用secret关键字生成(签名)的。这也很清楚。但是对我个人来说,一个大问题是如何使令牌无效。
OAuth2。我不明白为什么直接在服务器与客户端之间建立通信时应使用这种方法。据我了解,OAuth服务器用于发布具有受限范围的令牌,以允许其他应用程序访问用户信息而无需存储密码和登录名。对于社交网络而言,这是一个很好的解决方案,当用户想要在某个页面上进行注册时,服务器可以请求权限以获取用户信息(例如,从Twitter或Facebook获取信息),并使用用户数据等填充注册字段。
考虑在线商店的移动客户端。
第一个问题,我应该优先使用JWT而不是第一类令牌吗?就我需要在移动客户端上登录/注销用户而言,我需要将令牌存储在某个地方,或者在JWT的情况下,令牌应该在注销时失效。使用不同的方法来使令牌无效,其中之一是创建无效的令牌列表(黑名单)。嗯与令牌存储在表中并与用户相关联并且在注销时将其删除相比,表/文件的大小要大得多。
那么JWT令牌的好处是什么?
关于OAuth的第二个问题,在与服务器直接通信的情况下应该使用它吗?客户端和服务器之间仅发出令牌的另一层的目的是什么,但是通信将不是与oauth服务器,而是与主服务器。据我了解,OAuth服务器仅负责授予第三方应用访问用户私人信息的权限(令牌)。但是我的移动客户端应用程序不是第三方。
#1 楼
考虑第一种情况。每个客户都会获得一个随机ID,该ID可以持续到会话期间-如果您愿意,可以是几天。然后,将与该会话相关的信息存储在服务器端。它可以在文件或数据库中。假设您通过Cookie传递ID,但可以使用URL或HTTP标头。会话ID / Cookies
优点:
易于对客户端和服务器进行编码。
易于在有人注销时销毁会话。
缺点:
服务器端定期需要删除客户端未注销的过期会话。
每个HTTP请求都需要查找数据存储。
随着越来越多的用户拥有活动会话,存储需求也随之增加。
如果有多个前端HTTP服务器,所有这些服务器都需要访问存储的会话数据。与将其存储在一台服务器上相比,这可能需要更多的工作。更大的问题是数据存储将成为单点故障,并且可能成为瓶颈。
JSON Web令牌(JWT)
在传递而不是在服务器上传递的JWT中。
服务器端存储问题已消失。
客户端代码很容易。
缺点:
JWT的大小可能大于会话ID。由于它包含在每个HTTP请求中,因此可能会影响网络性能。
JWT中存储的数据可供客户端读取。这可能是一个问题。
服务器端需要代码来生成,验证和读取JWT。这并不难,但是有一些学习曲线,安全性取决于它。
任何获得签名密钥副本的人都可以创建JWT。您可能不知道什么时候发生。
某些库中有一个错误,它接受任何使用“无”算法签名的JWT,因此任何人都可以创建服务器可以信任的JWT。 br />
为了在JWT过期之前撤消JWT,您需要使用撤消列表。这使您回到试图避免的服务器端存储问题。
OAuth
OAuth通常用于身份验证(即身份),但可用于共享其他数据,例如用户已购买并有权下载的内容列表。它还可以用于授予访问权限以写入由第三方存储的数据。您可以使用OAuth对用户进行身份验证,然后使用服务器端存储或JWT来存储会话数据。
无代码供用户注册或重置他们的密码。
没有代码发送带有验证链接的电子邮件,然后验证地址。
用户无需学习/写下其他用户名和密码。
缺点:
您依赖第三方才能使用户使用您的服务。如果他们的服务中断或中止服务,则您需要找出其他解决方案。例如:如果用户的帐户数据从“ foo@a.com”更改为“ bar@b.com”,该如何迁移用户帐户数据?
通常,您必须为每个提供程序编写代码。例如Google,Facebook,Twitter。
您或您的用户可能有隐私问题。提供者知道哪些用户使用您的服务。
您信任提供者。提供者可以将对一个用户有效的令牌发行给其他人。这可能出于合法目的。
其他
两个会话ID和JWT都可以被多个用户复制和使用。您可以将客户端IP地址存储在JWT中并对其进行验证,但这可以防止客户端从Wi-Fi漫游到蜂窝网络。
评论
要添加到您的答案中,当用户希望使用其公司帐户进行注册时,oAuth可能没有用,该公司帐户通常不与任何社交网站或Google关联或链接。
–Aftab Naveed
16-10-11在5:06
我不知道为什么这是可接受的答案?它没有回答真正的问题,只是以其他方式修改了问题
–amd
17年1月15日在11:31
您说:“客户端可以读取存储在JWT中的数据。这可能是一个问题。如果有问题,为什么不使用JWE?
–银
17年1月31日在10:25
这个答案使苹果和橙子感到困惑。您不应将它们与OAuth 2.0(“授权”规范)进行比较。 OP需要了解的是:“资源所有者密码流”-这是作为授予的身份验证。
– OnurYıldırım
17/12/24在22:42
#2 楼
问问自己自己为什么需要使原始令牌失效。用户登录,生成令牌,然后关闭应用程序。
用户按下注销,一个新令牌生成并替换原始令牌。再一次,一切都很好。
您似乎担心两个令牌都挂在一起的情况。如果用户注销,然后以某种方式使用登录令牌发出请求,该怎么办?这种情况有多现实?这仅仅是注销过程中的问题,还是在许多可能存在多个令牌问题的情况下?
我自己不认为这值得担心。如果有人正在拦截和解码您的加密https数据,那么您会遇到更大的问题。
您可以通过在原始令牌上放置一个过期时间来为自己提供一些额外的保护。因此,如果最终被盗或被盗,那只能在短时间内有效。
否则,我认为您需要在服务器上具有状态信息。不要将令牌列入黑名单,而是将当前令牌的签名列入白名单。
评论
如果您认为某些客户端是恶意的,那么很容易看到会话将被复制并重新使用,因此您需要在服务器上对此进行反击。
–迈克尔·肖(Michael Shaw)
2015年10月5日在16:23
不好的主意,黑客以后可以使用它,或者只是强行使用...
– CROSP
2015年10月5日17:41
假设用户想从所有其他设备注销,则无法使用JWT。
–amd
17年1月15日在11:34
@amd不可能吗?如果我添加了nonce =(random)并且用户注销了,请替换现时该怎么办。似乎简单有效。
–西蒙B.
17年11月9日在19:11
#3 楼
您可以通过将盐值与用户一起存储并将盐用作用户令牌的一部分来处理您提到的JWT问题。然后,当您需要使令牌失效时,只需更改盐即可。我知道已经过去了几年了,但实际上我现在会做不同的事情。我想我将确保访问令牌的生存期相对较短,例如一个小时。我还要确保使用服务器上有状态的刷新令牌,然后当我想结束某人的会话时,可以通过将刷新令牌从服务器中删除来撤消刷新令牌。然后,一个小时后,该用户将被注销,必须再次登录才能重新获得访问权限。
评论
但是在这种情况下,它再次变为满状态,因此创建盐或使用任何其他方法的原因是什么,您可以在表中简单存储令牌并在应使其无效时删除它
– CROSP
2015年10月5日,下午4:39
您还可以基于时间使之失效。
– RibaldEddie
2015年10月5日,下午5:09
在这种情况下,到期时间有什么区别?当用户要从移动客户端注销时,如何根据时间使令牌无效?在这种情况下,似乎没有办法使API无状态。什么是最合适和最安全的解决方案?
– CROSP
2015年10月5日在7:42
最适合从单个设备注销的方法是确保除盐之外还使用clientId。我建议您查看Oauth-jwt承载令牌规范以了解情况。
– RibaldEddie
2015年10月5日15:37
感谢您的回答,但是我完全不明白为什么在这种情况下应该使用OAuth。
– CROSP
2015年10月5日17:28
#4 楼
宣誓不是认证协议,而是授权标准或协议。因此,例如,如果您使用“添加到Google日历”功能,那就是誓言。该应用程序将列出元素的Google API或指向要传递信息的各个挂钩的URL链接。如果要授权,则要OIDC或openID连接。
对于您的用例,我建议您综合上述所有内容。如果使用OIDC,则用户凭据将通过HTTPS向身份验证服务器进行身份验证。请求中将包含用户的用户名,密码以及应用程序的唯一随机生成的(客户端)ID。如果凭据有效且客户端ID有效,则服务器将使用一次性密码进行响应。然后,用户应用程序将使用该密码并将其传递给Web服务。 Web服务将密码传递回身份验证服务器,以验证密码是否合法。如果是这样,认证服务器将使用授权/访问令牌(AK)响应Web服务。现在,您可以采用以下两种方法之一:
2.1您可以将该令牌作为访问令牌存储在客户端应用程序中。然后让Web服务以刷新令牌进行响应。授权令牌的寿命可能为几个小时或几天,而刷新令牌的寿命将更短。您应该使用JWT作为刷新令牌,但是可以使用较小的随机生成的字符串作为刷新令牌。这样,您不必一定每次请求都传递AK。如果说5分钟过去了,并且服务器没有从用户那里获得刷新令牌,则服务器将断开与用户的连接并使所有令牌失效(AK和刷新)。唯一不利的一面是,如果AK被攻陷,则可能会冒用用户季的风险。
2.2(最推荐)访问令牌和授权通常通常是相同的,但从技术上讲可以是两个不同的令牌。如果用户已经通过身份验证并且您正在通过手机OS硬件API使用他或她的指纹或面部ID,那么这非常好。如果电话说是,这就是他或她,您只需通过无证书的API网关发送客户端ID即可访问密钥存储/存储库。网关将使用您先前生成的身份验证令牌进行响应。然后,应用程序可以将该令牌发送到Web服务,并且Web服务将使用访问令牌和刷新令牌进行响应。然后,您可以丢弃auth令牌,并保留访问和刷新令牌。
这里的想法是,在用户首次进行身份验证并生成auth令牌后,其使用寿命可能为3个月。现在,您不想将其保留在您的客户端电话上,因为如果它受到损害,则用户将被搞砸。因此,为什么要将其保存在不在手机上的密钥库中。现在,Web服务响应的访问令牌的使用寿命为一个小时,刷新令牌的使用寿命为5分钟。只要刷新令牌处于活动状态,会话就会保持活动状态。当您停止接收该刷新令牌时,会使刷新和访问令牌无效,终止会话,您仍然可以保留auth令牌。然后,您的授权应该是带有ES-256算法的JWT。您的访问令牌应该或可以使用RS-256,而刷新令牌可以使用HS-256。 RS&ES不要使用非对称加密,这意味着您需要使用公共密钥和私有密钥来生成它。 HS使用对称加密,这意味着仅使用一个密码或密钥来生成它。
评论
你好“宣誓不是认证协议,而是授权标准或协议。”您能否阐明“增强协议”与“认证标准或协议”之间的区别是什么?
–FélixGagnon-Grenier
19年3月3日,14:21
评论
谢谢,我最近很奇怪。我使用会话管理(Beaker),一个小时后删除了会话令牌。 Oauth似乎不合适。