去年年初做项目的时候接触到了OAuth认证,当时是选用了一个opensource的叫做KeyCloak的产品。项目中学到了很多关于认证的知识,之后一直想简单做下总结来着,后来一直拖了快一年。这几天又重新拾起来。可是,等自己查阅了几篇文章开始着手写的时候,才发现我对于OAuth和OpenIdConnect的理解实在是太浅薄了。
我知道想要深入理解和掌握OAuth 和OpenIdConnect自己还有相当大的距离,现在姑且只把我之前学到的东西总结一下,只当是自己的学习笔记了。
提到认证,可能最先想到的就是账号密码的认证方式。例如BASIC认证,在web服务器端设置好账号密码后可以应用到所有的http请求页中。但是,它的缺点非常显而易见:
・每次请求都需要输入账号密码
・每次通信内容中都有账号密码的信息,信息泄漏的危险性很大
因为传统账号密码认证方式的诸多缺点,web服务大部分都使用了如下方式:
只在第一次登陆的时候提交账号密码,然后把认证完了的状态存放在session里面,client通过把session_id传递给服务器,服务器就可以判定请求来自于谁,以及是不是经过认证了。
这种认证方式里面已经开始出现了认证和认可的概念了。认证是判定请求来自于谁。而认可是判定是不是经过认证了。
(据说认证和认可就是OAuth和OpenIdConnect的区别)
上面的方式基本实现了认证和认可的功能,但是后来出现了稍微复杂的情况:如何能在多个服务器之间共享认证和认可的信息。例如如何用QQ号登陆百度就是一个很典型的例子。
这种情况下就需要用到OAuth认证方式了,先简单概括一下:
QQ拥有用户信息,负责认证,拿QQ号登录成功以后,QQ将认可状态交付给百度,百度记录下认证状态,然后就可以访问百度的服务了(也就是说百度负责认可)。
具体的认证过程可以参照下面的图示:
※本图来自于 http://www.atmarkit.co.jp/
在这个流程中有那么几个关键词需要解释一下:
・client_id、secrect
由调用的service provider(上面例子中的QQ服务器端)发行的用来识别client(百度)的信息。一般来说,secret不用每次都发送。
・code
认可代码,用户认证完毕以后,由service provider返回的代码,受到认可代码就可以判定认证OK了。
・access_token
认证完毕以后,如果想要调用service provider的api的话,需要把认可代码发送给service provider来换取access_token。之后使用access_token来调用api。service provider会通过access_token来判定是否认证完了。
・refresh_token
access_token的有效期限过期的情况下,通过refresh_token可以重新获得access_token。
现在很多大服务商都提供了OAuth&OpenIDConnect的认证服务,一方面对服务提供商来说可以增加用户对于服务器的依赖性,另一方面服务调用方可以减轻用户注册时的繁杂手续,是一个双赢的选择。