kestrel 网页授权
说明
- 本文提到的
http://www.kestrel.com
为 授权服务器,视实际情况进行修改 - 目前提供的调用的客户端信息
{client_id:"C001", client_secret:"123456"}
网页授权流程
- 引导用户进入授权页面同意授权,获取code
- 通过code换取网页授权
access_token
(与基础支持中的access_token
不同) - 如果需要,开发者可以刷新网页授权
access_token
,避免过期 - 通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
第一步: 用户同意授权,获取code
引导用户进入授权页面,地址如下:
http://www.kestrel.com/oauth/authorize?client_id=CLIENT_ID&response_type=code&redirect_uri=<REDIRECT_URI 接收code的接口地址>&state=STATE
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
client_id | 是 | 第三方应用唯一标识 |
redirect_uri | 是 | 授权后重定向的回调链接地址,请使用urlEncode对链接进行处理 |
response_type | 是 | 返回类型,请填写code |
scope | 是 | api_userinfo (弹出授权页面,可通过openid拿到用户信息 |
state | 否 | 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节,可用于防范csrf攻击(参考本文的防范csrf 攻击 ) |
用户同意授权后
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。
code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,有效时长5分钟。
第二步:通过code换取网页授权access_token
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=authorization_code&code=<CODE>&redirect_uri=http://www.myapp.com/verifyCode' "http://client_id:client_secret@www.kestrel.com/oauth/token"
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
client_id | 是 | 第三方应用唯一标识 |
client_secret | 是 | 第三方应用appsecret |
redirect_uri | 是 | 回调链接地址,请使用urlEncode对链接进行处理 |
code | 是 | 填写第一步获取的code参数 |
grant_type | 是 | 填写为authorization_code |
返回说明:
### 正确时返回的JSON数据包如下
{
"access_token": "T2tRZERkTWJENkdHbGR2UFBRcTVTT25XRm5ZWlhzWmZXVEt6NWE5QmdKN2Y5RnFpZ2Zac1lTMkRZcFdMWEZaMWhFS0luMFYxN2NjWkp0S3BMMTVLZE9ZRjAzVVVhMQ==",
"token_type": "bearer",
"refresh_token": "a308c3c8-7bfa-4270-9d2d-ef3c760720ab",
"expires_in": 6514,
"scope": "api_userinfo",
"openid": "1234567890"
}
### 使用错误的code时返回
{
"error": "invalid_grant",
"error_description": "Invalid authorization code: 93efc2638ee84281aa7555589450d349"
}
第三步:刷新access_token(如果需要)
由于access_token
拥有较短的有效期,当access_token
超时后,可以使用refresh_token
进行刷新,refresh_token
有效期为30天,当refresh_token
失效之后,需要用户重新授权。
获取第二步的refresh_token后,请求以下链接获取access_token:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type= refresh_token&scope=api_userinfo&refresh_token=<REFRESH_TOKEN>’ "http://client_id:client_secret@www.kestrel.com/oauth/token"
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
client_id | 是 | 第三方应用唯一标识 |
client_secret | 是 | 第三方应用secret |
refresh_token | 是 | 填写通过access_token获取到的refresh_token参数 |
grant_type | 是 | 填写为refresh_token |
返回说明
## 正确时返回的JSON数据包如下:
{
"access_token": "Nmc1RVR6cGtRNWk2VHJRdkhLblozdVJ3WERPSVc4dzRCc3JLTVhhVHZnYU1aeTZOcEtkZ0UwT3NrTEFzdEtCemRVTkFEcXdBVW1QSVVLUzFnNVkwMmNsMHlDemJRQQ==",
"token_type": "bearer",
"refresh_token": "a308c3c8-7bfa-4270-9d2d-ef3c760720ab",
"expires_in": 7199,
"scope": "api_userinfo",
"openid": "1234567890"
}
## 异常
{
"error": "invalid_grant",
"error_description": "Invalid refresh token: a308c3c8-7bfa-4270-9d2d-ef3c760720ab1"
}
第四步:拉取用户信息(需scope为 api_userinfo)
请求方法
http:GET(请使用https协议) http://www.kestrel.com/demo/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
access_token | 是 | 第二步的refresh_token |
openid | 是 | 用户的唯一标识 |
有效时长说明
- code 有效时长 60 * 5 秒 (5分钟)
- access_token 有效时长 60 * 60 * 2 秒 (2小时)
- refresh_token 有效时长 60 * 60 * 24 * 30 秒(30 天)
防范csrf 攻击
作为第三方应用的开发者,只需在OAuth认证过程中加入state参数,并验证它的参数值即可。具体细节如下:
- 在将用户重定向到OAuth2的Authorization Endpoint去的时候,为用户生成一个随机的字符串,并作为
state
参数加入到URL中。 - 在收到OAuth2服务提供者返回的
Authorization Code
请求的时候,验证接收到的state参数值。如果是正确合法的请求,那么此时接受到的参数值应该和上一步提到的为该用户生成的state参数值完全一致,否则就是异常请求。 -
state
参数值需要具备下面几个特性:- 不可预测性:足够的随机,使得攻击者难以猜到正确的参数值
- 关联性:
state
参数值和当前用户会话(user session)是相互关联的 - 唯一性:每个用户,甚至每次请求生成的
state
参数值都是唯一的 - 时效性:
state
参数一旦被使用则立即失效