简介
在前面两个章节中,我们介绍了授权码流程和简化流程,这两种流程都涉及到了用户交互,也就是需要用户在授权服务器登录并且完成授权。
在这一章节中,我们将介绍的是密码模式(Resource Owner Credential Flow),它和之前两者的最大不同点在于应用是可以访问到用户在授权服务器的用户名密码的(所以我们在标题中说他是半进化的)。也就是说用户将自己的用户名密码交付给应用,应用使用用户的用户名密码直接获取授权而授权过程中不再需要用户交互。
这种模式其实需要用户对应用有非常强的认可,一般只用于公司内部软件中。否则我们很难避免应用滥用用户的认证信息。
令牌请求a. 要求用户认证信息
由于接下来的授权过程不会涉及到用户交互,所以应用需要提前获得用户在授权服务器上的用户名和密码。
这里,如果使用的公司的应用,那么很大可能性登录应用的用户名密码和登录授权服务器的用户名密码一致。那么可能在登录应用的时候,授权操作也一并完成了,之后就不再需要另外的步骤来输入授权服务器端的认证信息。还有的方式就是在用户输入用户名密码之后将认证信息保存在了本地,虽然不是很推荐在设备本地保存用户名密码,但是确实有应用是这么做的。
b. 发送请求
有了用户名密码之后,应用就可以发送令牌的请求了。这里的请求和授权码模式的比较相似,使用的POST请求并且需要应用的认证信息。
这里使用到的参数和授权码模式的基本相似:
client_id:和之前两种模式一致,应用需要提前在授权服务器上进行注册,获得唯一的一个id。并且在注册的时候也会声明应用使用的认证信息。client_id和认证信息会作为Authorization 消息头发送到授权服务器。grant_type:这里使用的是password代表是通过用户提供的用户名和密码进行授权,这样后面的流程中就不再需要用户交互了user_name: 用户在授权服务器上的用户名password:用户在授权服务器上使用的密码
c. 令牌请求响应
这里响应的返回数据就和授权码模式的返回数据一模一样。这里就不再累述。
访问资源
应用在获取了令牌access_token之后就可以直接访问资源服务器了。
说说用户名密码和refresh_token
由于密码模式也会有refresh_token 返回,那么意味着应用在后续的访问中可以通过refresh_token来更新access_token以保证长期的访问权限(这里refresh_token的使用和授权码模式一致,因此不再累述)。同时也就意味着用户名密码可能只会使用一次。在这种情况下,推荐的方式是在本地保存refresh_token而不是用户名密码。这样只需要在用户第一次需要进行授权的时候让用户输入认证信息,或者在登录应用的时候直接完成授权,而不需要额外保存用户名密码。这样比较好的安全性,而这也是这个密码模式相对于传统的用户名密码的一个优势。
传统模式下,如果应用保存了用户名和密码,一旦用户不想再对此应用进行授权,唯一的方式就是更改密码。如果用户在多个应用使用了这个用户名密码,那就意味着用户需要同时在多个应用中进行密码用户名重新输入的操作。使用了密码模式之后,如果应用不进行密码和用户名的保存而只是使用refresh_token的话,那么用户就能很方便的在授权服务器上操作将授权收回。
当然了,最后要说的是,会不会存储用户名密码还是取决于开发者或者应用管理者的节操了。如果他们选择无节操的保存了用户名密码,那么。。。
密码模式使用场景
由于应用会获得用户在授权服务器中的用户名和密码,强烈建议用户只在公司的官方应用中或者一些大众普及度高的官方产品中输入认证信息。如果是一些第三方产品使用了密码模式,建议大家尽量避免使用。毕竟节操这种东西。。。你懂的。。。
小结用户在授权服务器上的认证信息会暴露给应用密码模式中间不涉及用户交互应用应该保存refresh_token而不是用户的认证信息。