点关注,不迷路,每天更新大量前端资料
前端实现第三方登录之OAuth2.0协议
OAuth 2.0 规定了四种获得令牌的流程。我们可以选择最适合自己的那一种,向第三方应用颁发令牌。下面就是这四种授权方式。
- 授权码模式(authorization-code)
- 简化模式(implicit)
- 密码式(password):
- 客户端凭证(client credentials)
不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。
授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
比如我们经常用某些公众号,用一些论坛,有用QQ,微信登录什么的,需要你在QQ,微信的界面上授权,这些号、论坛就可以拿到你的个人信息,头像什么的,但他们没有你的用户密码。生活中,我去银行办理过代扣水电煤,银行确认我的身份,然后签一个代扣合同,给我回执,之后水电煤公司就直接从我的账户划钱过去了。但公司不知道我的密码,不能代做其它没授权的操作,差不多上OAuth2.0就是解决上面的问题。
OAuth2.0的相同理念的生活场景举例
比如我有银行账户,想授权朋友查看账户金额,不告诉他密码,应该怎么办呢?
我和朋友去银行,银行先后验证我们俩的身份证。银行让我签一个授权合同,上面写着我授权朋友查我的账户,银行给我和朋友各一份合同凭证。银行后台登记朋友拿这个凭证可以查我的账户这样一条信息。之后朋友拿着凭证和他自己的身份证,果然查到了我的账户信息。上面的分析蛮简单的,貌似也没有什么问题。朋友不可能转账,因为银行会查授权合同,我的合同被其它人知道了,别人也不可能查我的账户,因为只授权给朋友。那么把上面的过程转化到应用之中去。我在某论坛上操作,希望用QQ登录。(论坛认为我有QQ号的,论坛本身也在QQ注册过自己的应用的。就如同去银行,这个银行必须可以鉴定我们双方的身份。)
点了QQ登录,那论坛就引导跳转到QQ的授权页面了。(这个过程中,论坛必须提供了自己的登录信息,QQ那边认证了,才出现授权页面。)在这个页面里,我要登录一下QQ了。前面已经认证过论坛了,现在登录就是认证我了。登录成功后,QQ显示出授权的内容,让我确认,我点了确认。(类似银行让我签授权合同了)确认之后,按说是银行将确认了的授权合同,一式三份,给我和论坛各一份。给我看合同并不重要,可以后台存下来,我随时可以登录后,在已授权的地方查看给过的授权信息。关键是怎么给论坛呢?事实上论坛当初转到QQ授权页面的时候,除了提供自己的身份,还有一个redirectUrl。当我点了授权后,QQ把合同给了这个Url,等于就是给了论坛了。论坛拿到了合同,再把自己的登录信息给QQ再验证一下,QQ就把我的资料给了论坛了。如果这里不再验证论坛的身份,论坛把合同卖给其它地方怎么办?那就不安全了!当然我也可能把合同转给其它地方用,来陷害是这个论坛在用。
这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
OAuth认证和授权的过程如下:
1、用户访问第三方网站网站,想对用户存放在服务商的某些资源进行操作。
2、第三方网站向服务商请求一个临时令牌。
3、服务商验证第三方网站的身份后,授予一个临时令牌。
4、第三方网站获得临时令牌后,将用户导向至服务商的授权页面请求用户授权,然后这个过程中将临时令牌和第三方网站的返回地址发送给服务商。
5、用户在服务商的授权页面上输入自己的用户名和密码,授权第三方网站访问所相应的资源。
6、授权成功后,服务商将用户导向第三方网站的返回地址。
7、第三方网站根据临时令牌从服务商那里获取访问令牌。
8、服务商根据令牌和用户的授权情况授予第三方网站访问令牌。
9、第三方网站使用获取到的访问令牌访问存放在服务商的对应的用户资源。
主要步骤
第一步,A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权用户数据给 A 网站使用。下面就是 A 网站跳转 B 网站的一个示意链接。
https://b.com/oauth/authorize? response_type=code& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read
上面 URL 中,response_type参数表示要求返回授权码(code),client_id参数让 B 知道是谁在请求,redirect_uri参数是 B 接受或拒绝请求后的跳转网址,scope参数表示要求的授权范围(这里是只读)。
第二步,用户跳转后,B 网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时 B 网站就会跳回redirect_uri参数指定的网址。跳转时,会传回一个授权码,就像下面这样。https://a.com/callback?code=AUTHORIZATION_CODE
上面 URL 中,code参数就是授权码。
第三步,A 网站拿到授权码以后,就可以在后端,向 B 网站请求令牌
https://b.com/oauth/token? client_id=CLIENT_ID& client_secret=CLIENT_SECRET& grant_type=authorization_code& code=AUTHORIZATION_CODE& redirect_uri=CALLBACK_URL
上面 URL 中,client_id参数和client_secret参数用来让 B 确认 A 的身份(client_secret参数是保密的,因此只能在后端发请求),grant_type参数的值是AUTHORIZATION_CODE,表示采用的授权方式是授权码,code参数是上一步拿到的授权码,redirect_uri参数是令牌颁发后的回调网址。
第四步,B 网站收到请求以后,就会颁发令牌。具体做法是向redirect_uri指定的网址,发送一段 JSON 数据
{ "access_token":"ACCESS_TOKEN