-
Notifications
You must be signed in to change notification settings - Fork 70
Oauth2
饭否网可以使用OAuth2作为验证与授权协议,目前只支持网站类型的应用。
用户授权第三方应用成功之后,应用会得到一个_access token_, 使用这个 access token, 应用可以访问饭否API2来读取、写入数据。下面将描述网站类型的应用如何获取用户的_access token_
使用饭否OAuth需要在[v2ex](http://www.v2ex.com/go/fanfou v2ex)发帖申请一个饭否应用,申请时请写明以下信息:
- 应用名称
- 开发者饭否id
- 应用主页
- 应用回调地址(此地址用于授权时检查,必须与下文中提及的
redirect_uri
一致)
管理员会及时批准该应用,之后开发者可以在 饭否应用详细信息 看到应用的详细信息,以下几项会在后面的文档中使用
- ClientID
- ClientSecret
- AuthorizeURL
- AccessTokenURL
开发者拿到应用的详细信息之后,就可以进行认证了
网站类型的第三方应用获取授权应遵循以下流程
第三方应用首先将用户重定向接到饭否的用户授权页面(AuthorizeURL),并且在url中附带应用的client_id
、redirect_uri
、response_type=code
,url具体的格式为:
AuthorizeURL?redirect_uri=$redirect_uri&response_type=code&client_id=$client_id
其中的$redirect_uri
是开发者申请应用时提供的应用回调地址,$client_id
是开发者在饭否应用详细信息 看到的ClientID
例如:
https://fanfou.com/oauth2/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2%2Fauthorize&response_type=code&client_id=36ba8914e5f2b8888f965a507fc3928c
饭否提供了一个“使用饭否帐号登录”的图标, 开发者可以使用这个图标来提示用户登录
用户授权页会提示用户“第三方应用希望操作你在饭否伤的数据”,用户此时可以选择“同意”或者“拒绝”。
用户拒绝向第三方应用授权后,饭否会将用户重定向会开发者的页面,并且带上错误信息。具体格式为:
redirect_uri?error=access_denied
此时开发者可以自行处理此错误
用户同意向第三方应用授权后,饭否会将用户重定向会开发者的页面,并且带上authorization code。具体格式为:
redirect_uri?code=$authorization_code
例如:
http://localhost:8080/oauth2/authorize?code=663468c87e46789ca58356712d580424
第三方应用获取authorization code
之后,就可以使用它来向服务器交换用户的access token
(authorization code在30秒之后过期,所以第三方应用必须在30秒内用authorization code来交换access token),具体方式为发起如下如下请求:
AccessTokenURL?client_id=$client_id&
client_secret=$client_secret&
redirect_uri=$redirect_uri&
code=$authorization_code&
grant_type=authorization_code
其中的$client_id
、$client_secret
、$redirect_uri
都是饭否应用详细信息显示的信息;$code
是饭否返回的authorization_code
如果请求的方式正确,饭否将会以json的方式返回access_token
、token有效期(expires_in
,单位为秒)、应用的授权范围(scope
,暂时未生效)和refresh_token
(用于刷新access_token
,详见refresh_token。例如:
{
"access_token": "~68NKILzDyRs-c538eb0be6ce843ac6ca3c7fc81a0e72",
"expires_in": 3600,
"scope": null,
"refresh_token": "~68NKILzDyRs-82671540cdf1f716a87a9d95c2fbce0a"
}
你可以使用如下python代码片段来向服务器交换access token
params = {'client_id': CLIENT_ID
'redirect_uri': REDIRECT_URI,
'client_secret': CLIENT_SECRET,
'code': code_from_fanfou,
'grant_type': 'authorization_code'}
request = urllib2.Request(AccessTokenURL,
urllib.urlencode(params))
response = urllib2.urlopen(request)
body = response.read()
access_results = json.loads(body)
出于安全考虑,access_token
的有效期被设置为3600秒,超过这个时间之后,access_token
便无法继续使用,这时候需要使用服务器返回的refresh_token
来刷新access_token
, 刷新的方法是向https://fanfou.com/oauth2.token
使用POST
方法发送如下字段client_id
、client_secret
、redirect_uri
、grant_type
和refresh_token
。
例如:
curl "https://fanfou.com/oauth2.token" -d"client_id=36ba8914e5f2b8888f965a507fc3928c&client_secret=d0b8ff1f91964453b542bbcfb0c447c0&redirect_uri=http://localhost:8080/oauth2/authorize&grant_type=refresh_token&refresh_token=~68NKILzDyRs-82671540cdf1f716a87a9d95c2fbce0a"
如果参数全部正确无误,服务器则会返回新的access_token
和refresh_token
(因为refresh_token
也会1209600秒之后过期),应用应该使用返回的值替换旧的token。
一次成功的refresh_token请求返回如下结果:
{
"access_token": "~68NKILzDyRs-7299164989ecc7308fe5933b78bf69e7",
"expires_in": 3600,
"scope": { },
"refresh_token": "~68NKILzDyRs-5fd98ab15eec14bc51ff1fdd1bdf4819"
}
第三方应用凭有效的access_token
,通过饭否API,可以获取用户权限,访问用户数据。
获取用户权限的方法是在POST
、GET
中加上如下参数oauth_token=$access_token
,例如,可以使用curl来访问用户的个人信息:
curl "http://api.fanfou.com/account/verify_credentials.json?oauth_token=~68NKILzDyRs-c538eb0be6ce843ac6ca3c7fc81a0e72"