Oauth2
0. OAuth2简介
OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息(如QQ、微信等),而不需要将用户名和密码提供给第三方网站.
应用场景:使用依赖于外部的第三方认证提供者.当用户登录站点时,会看到连接到第三方提供商的入口(如使用微信登录).用户点击以后被重定向到对应的认证服务商网站,获得用户的授权后就可以访问到需要的信息,然后重定向回来.
四种授权方式
- 授权码(authorization-code)
- 隐藏式(implicit)
- 密码式(password):
- 客户端凭证(client credentials)
最常用的为授权码方式.因此下面的文章介绍该种方式.
授权码(authorization code)方式,指的是第三方应用先申请一个授权码,再用该码获取令牌.使用令牌换取数据.如下图所示:
1 | graph TD |
1 | +--------+ +---------------+ |
1. 网站实现QQ登录(未实操)
1.1 申请appid和appkey
appid:应用的唯一标识.在OAuth2.0认证过程中,appid的值即为oauth_consumer_key的值.
appkey:appid对应的密钥,访问用户资源时用来验证应用的合法性.在OAuth2.0认证过程中,appkey的值即为oauth_consumer_secret的值.
1.2 获取Authorization Code
请求网址: https://graph.qq.com/oauth2.0/authorize
请求方法:GET
请求参数:
参数 | 是否必须 | 含义 |
---|---|---|
response_type | 必须 | 授权类型,此值固定为“code”. |
client_id | 必须 | 申请QQ登录成功后,分配给应用的appid. |
redirect_uri | 必须 | 成功授权后的回调地址,必须是注册appid时填写的主域名下的地址,建议设置为网站首页或网站的用户中心.注意需要将url进行URLEncode. |
state | 必须 | client端的状态值.用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回.请务必严格按照流程检查用户与state参数状态的绑定. |
scope | 可选 | 请求用户授权时向用户显示的可进行授权的列表.可填写的值是API文档中列出的接口,以及一些动作型的授权(目前仅有:do_like),如果要填写多个接口名称,请用逗号隔开.例如:scope=get_user_info,list_album,upload_pic,do_like.不传则默认请求对接口get_user_info进行授权.建议控制授权项的数量,只传入必要的接口名称,因为授权项越多,用户越可能拒绝进行任何授权. |
display | 可选 | 仅PC网站接入时使用.用于展示的样式.不传则默认展示为PC下的样式.如果传入“mobile”,则展示为mobile端下的样式. |
a). 如果用户成功登录并授权,则会跳转到指定的回调地址,并在redirect_uri地址后带上Authorization Code和原始的state值.如:
PC网站:http://graph.qq.com/demo/index.jsp?code=9A5F...06AF&state=testb). code的有效期是10分钟
1.3 通过Authorization Code获取Access Token
请求网址:https://graph.qq.com/oauth2.0/token
请求方法:GET
请求参数:
参数 | 是否必须 | 含义 |
---|---|---|
grant_type | 必须 | 授权类型,此值固定为“authorization_code” |
client_id | 必须 | 申请QQ登录成功后,分配给网站的appid |
client_secret | 必须 | 申请QQ登录成功后,分配给网站的appkey |
code | 必须 | 上一步返回的authorization code |
redirect_uri | 必须 | 与上面一步中传入的redirect_uri保持一致 |
成功返回得到返回包,有如下信息:
参数说明 | 描述 |
---|---|
access_token | 授权令牌 |
expires_in | 该access token的有效期,单位为秒 |
refresh_token | 在授权自动续期步骤中,获取新的Access_Token时需要提供的参数 |
1.4 换取用户信息
请求网址:https://graph.qq.com/oauth2.0/me
请求方法:GET
请求参数:
参数 | 是否必须 | 含义 |
---|---|---|
access_token | 必须 | 上一步获取到的access_token |
将返回用户OpenID.
1.5 获取到access_token和OpenID后,就可以调用QQ的API获取用户信息(如头像、说说等).API列表
2. 以微信小程序登录为例,使用OAuth2标准
如图示小程序的登录流程(图片来源:微信官方文档):
2.1 用户点击登录,获取code
调用wx.login()函数,获取code
1 | wx.login({ |
如图所示:
2.2 wx.request()发送code给开发者服务器
1 | if (res.code) { |
2.3开发者服务器接收code,并向验证服务器发送请求获取access_token
servlet中接收code,调用getAccessToken()方法向验证服务器发送请求获取access_token
1 | package servlet; |
getAccessToken()方法:
1 | package services;/* |
这样就获取到了access_token,可以使用access_token调用相应的API换取用户信息.