人人OAuth 2.0文档

时间:2022-06-29 04:49:27

人人OAuth 2.0文档已经升级,老文档请浏览 老Auhentication文档

人人开放平台使用OAuth 2.0作为验证与授权协议。我们支持一系列OAuth 2.0验证授权流程,支持网站站内应用手机客户端桌面客户端。本文档概述了如何使用各种人人OAuth 2.0的各种验证授权流程,样例代码使用PHP作为服务端编程语言,HTML/JavaScript作为客户端编程语言。样例代码非常直观,也可以很容易的翻译成其他编程语言。

目录

[隐藏]

[编辑] 用户登录

人人开放平台支持3种不同的OAuth 2.0验证与授权流程:

  • 服务端流程(协议中Authorization Code Flow)。此流程适用于在Web服务端调用REST API的的应用。例如:网站站内应用
  • 客户端流程(协议中Implicit Flow)。注意:此流程适用于在客户端调用REST API的应用。例如:后端无Web Server支持的手机客户端桌面客户端,运行于浏览器内部的JavaScript、ActionScript应用(浏览器插件、纯Flash应用)。
  • 用户名密码流程(协议中Resource Owner Password Credentials Flow)。此流程适用于无法使用浏览器发起服务端和客户端验流程的应用。

无论你使用那个流程,人人OAuth 2.0都会涉及到了三个步骤:

  • 用户验证:确保用户是谁;
  • 应用授权:确保用户知道他授予什么样的数据和权限给您的应用;
  • 应用验证:确保用户授予权限的应用是您的应用,而不是其他应用。

当完成这些步骤后,您的应用可以获得一个用户的Access Token。使这个Access Token,您的应用可以获取这个用户的信息,并可以以这个用户的身份做出相应的动作(发状态、上传照片)。

[编辑] 服务端流程

登录流程开始于重定向用户浏览器(如果需要的话,可以弹出窗口或打开新页面)到人人OAuth 2.0的Authorize Endpoint,并传递三个必须参数

  • client_id:必须参数。在开发者中心注册应用时获得的API Key。
  • redirect_uri:流程结束后要跳转回得URL。redirect_uri所在的域名必须在开发者中心注册应用后,填写在编辑属性选项卡中填写到服务器域名中,人人OAuth2.0用以检查跳转的合法性。关于redirect_uri的验证方式的详细信息请参考 redirect_uri验证配置
  • response_type:必须参数。服务端流程,此值固定为“code”。
https://graph.renren.com/oauth/authorize? client_id=YOUR_API_KEY&redirect_uri=YOUR_CALLBACK_URL&response_type=code

如果用户已经登录,人人OAuth 2.0会校验存储在用户浏览器中的Cookie。如果用户没有登录,人人OAuth 2.0会为用户展示登录页面,让用户输入用户名和密码:

人人OAuth 2.0文档

当人人OAuth 2.0成功验证用户之后,会为用户展示授权页面,让用户为应用授权:

人人OAuth 2.0文档

默认情况下,会要求用户授予用于访问基本信息的权限,例如用户公共信息、好友关系等。如果应用需要的权限超过基本信息权限,就需要要求用户授予深层次的权限。这个过程是通过添加人人OAuth 2.0 'scope'请求参数实现的:

  • scope:非必须参数。以空格分隔的权限列表,若不传递此参数,代表请求用户的默认权限。全部权限请参考'权限列表'

下面的例子展示了如何要求用户授予访问用户的相册新鲜事的权限:

https://graph.renren.com/oauth/authorize? client_id=YOUR_API_KEY&redirect_uri=YOUR_CALLBACK_URL&response_type=code&scope=read_user_album+read_user_feed

注意:上述scope参数中的'+',是空格(' ')的URL Encode编码。

人人OAuth 2.0文档

如果用户不同意授权(点击关闭),应用将不会被授权。人人OAuth2.0会将用户的浏览器重定向(通过HTTP 302)到redirect_uri参数对应的URL上,并在Query中带上相应的错误信息。

http://YOUR_CALBACK_URL?error=nvalid_request& &error_description=The+request+is+missing+a+required+parameter:+client_id.

如果用户同意授权(点击连接),应用将会被授权。人人OAuth2.0会将用户的浏览器重定向(通过HTTP 302)到redirect_uri参数对应的URL上,并在Query中使用'code'参数返回一个Authorization Code。

http://YOUR_CALBACK_URL?code=A_CODE_GENERATED_BY_SERVER

Authorize Code可以在redirect_uri后端程序中获得(例如:Java request.getParameter("code");)。获得到Authorization Code后,你可以进行流程的下一步—应用验证,以便获得可以调用REST API的Access Token。

应用验证需要使用HTTP POST请求人人OAuth 2.0的Access Token Endpoint,并需要带上一系列需要的参数:

注意:人人OAuth2.0支持多种传递“client_id”和“client_secret”的方式,包括:URI Query Parameter、Form-Encoded Body Parameter和RFC2617定义的HTTP Basic Authentication,详细信息请浏览Client Authenticated

https://graph.renren.com/oauth/token?grant_type=authorization_code& client_id=YOUR_API_KEY&redirect_uri=YOUR_CALLBACK_URL& client_secret=YOUR_SECRET_KEY&code=THE_CODE_FROM_ABOVE

如果应用验证通过(client_id与client_secret匹配,redirect_uri与获取Authorization Code时传递的redirect_uri保持一致),并且从用户获取的Authorization Code也正确,人人OAuth 2.0会返回Access Token相关的信息:

{ "access_token": "10000|5.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-222209506", "expires_in": 87063, "refresh_token": "10000|0.385d55f8615fdfd9edb7c4b5ebdc3e39-222209506", "scope": "read_user_album read_user_feed"}
  • access_token:获取的Access Token;
  • expires_in:Access Token的有效期,以秒为单位;
  • refresh_token:用于刷新Access Token 的 Refresh Token,长期有效,不会过期;
  • scope:Access Token最终的访问范围,既用户实际授予的权限列表(用户在授权页面时,有可能会取消掉某些请求的权限)。关于权限的具体信息请参考权限列表

如果应用验证过程中出错,人人OAuth 2.0将返回HTTP 401(应用验证失败)或HTTP 400(参数错误),并在HTTP Body中返回错误信息:

{ "error": "invalid_request", "error_description": "The request is missing a required parameter: client_id"}
  • error:错误码,有关错误码的详细信息请浏览错误码
  • error_description:一段人类可读的文字,用来帮助理解和解决发生的错误;
  • error_uri:一个人类可读的网页URI,带有关于错误的信息,用来为终端用户提供与错误有关的额外信息。

下图展示了服务端流程HTTP请求的全过程:

人人OAuth 2.0文档

下面的PHP示例代码简要展示了服务端流程,并考虑了CSRF攻击的防范工作:

<?php $app_id = "YOUR_API_KEY"; $app_secret = "YOUR_APP_SECRET"; $my_url = "YOUR_CALLBACK_URL"; session_start(); $code = $_REQUEST["code"]; if(empty($code)) { $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection $dialog_url = "http://graph.renren.com/oauth/authorize?client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state=" . $_SESSION['state']; echo("<script> top.location.href='" . $dialog_url . "'</script>"); } if($_REQUEST['state'] == $_SESSION['state']) { $token_url = "https://graph.renren.com/oauth/token?" . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url) . "&client_secret=" . $app_secret . "&code=" . $code; $response = @file_get_contents($token_url); $params = null; parse_str($response, $params); $graph_url = "https://api.renren.com/v2/user?access_token=" . $params['access_token']; $user = json_decode(file_get_contents($graph_url)); echo("Hello " . $user->name); } else { echo("The state does not match. You may be a victim of CSRF."); } ?>

[编辑] 客户端流程

客户端流程同样使用人人OAuth 2.0的Authorize Endpoint来实现用户验证和应用验证。唯一不同点是需要指定'response_type'参数为'token':

https://graph.renren.com/oauth/authorize? client_id=YOUR_API_KEY&redirect_uri=YOUR_CALLBACK_URL&response_type=token

与服务端流程一样,可以使用'scope'参数来请求深层次权限,实现应用授权:

https://graph.renren.com/oauth/authorize? client_id=YOUR_API_KEY&redirect_uri=YOUR_CALLBACK_URL&scope=email,read_stream& response_type=token

与服务端流程一样,当用户验证和应用授权通过后,人人OAuth2.0会将用户的浏览器重定向(通过HTTP 302)到redirect_uri参数对应的URL上。与服务端流程不同的是,客户端流程不会返回code参数,而是在URI Fragment中返回Access Token(#access_token=...):

http://YOUR_CALLBACK_URL#access_token=1000%7C5.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-222209506&expires_in=64090

由于返回的Access Token是在URI Fragment中返回,只有客户端代码(例如:例如运行与浏览器中的JavaScript、有浏览器控件支持的客户端代码)才可以获取Access Token。

应用验证是通过验证'redirect_uri'实现的,关于redirect_uri的验证方式的详细信息请参考 redirect_uri验证配置

下图展示了客户端流程HTTP请求的全过程:

人人OAuth 2.0文档

下面的HTML/JavaScript示例代码简要展示了客户端流程:

<html> <head> <title>Client Flow Example</title> </head> <body> <script> function displayUser(user) { var userName = document.getElementById('userName'); var greetingText = document.createTextNode('Greetings, ' + user.name + '.'); userName.appendChild(greetingText); } var appID = "YOUR_API_KEY"; if (window.location.hash.length == 0) { var path = 'https://graph.renren.com/oauth/authorize?'; var queryParams = ['client_id=' + appID, 'redirect_uri=' + window.location, 'response_type=token']; var query = queryParams.join('&'); var url = path + query; window.open(url); } else { var accessToken = window.location.hash.substring(1); var path = "https://api.renren.com/v2/user?"; var queryParams = [accessToken, 'callback=displayUser']; var query = queryParams.join('&'); var url = path + query; // use jsonp to call the rest api var script = document.createElement('script'); script.src = url; document.body.appendChild(script); } </script> <p id="userName"></p> </body> </html>

[编辑] 用户名密码端流程

注意:使用用户名密码端流程的权限需要提前申请,有关申请细节参见 申请Resource Owner Password Credentials Access Grant

用户名密码流程需要使用HTTP POST请求人人OAuth 2.0的Access Token Endpoint,并需要带上一系列需要的参数:

  • grant_type:使用Resource Owner Password Credentials作为Access Grant时,此值为“password”。
  • username:人人网用户的用户名;
  • password:人人网用户的密码;
  • client_id:在开发者中心注册应用时获得的API Key;
  • client_secret:在开发者中心注册应用时获得的Secret Key。此值不要嵌入到任何要发布到服务端以外的代码里(这种场景应该使用客户端流程);
  • scope:非必须参数。以空格分隔的权限列表,若不传递此参数,代表请求用户的默认权限。全部权限请参考'权限列表'

注意:人人OAuth2.0支持多种传递“client_id”和“client_secret”的方式,包括:URI Query Parameter、Form-Encoded Body Parameter和RFC2617定义的HTTP Basic Authentication,详细信息请浏览Client Authenticated

请求如下:

https://graph.renren.com/oauth/token?
    grant_type=password&
    username=USERNAME&
    password=PASSWORD&
    client_id=YOUR_API_KEY&
    client_secret=YOUR_SECRET_KEY&
    scope=...

如果用户验证通过(用户名密码正确),并且应用验证通过,人人OAuth 2.0会返回Access Token相关的信息:

{ "access_token": "10000|5.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-222209506", "expires_in": 87063, "refresh_token": "10000|0.385d55f8615fdfd9edb7c4b5ebdc3e39-222209506", "scope": "read_user_album read_user_feed"}
  • access_token:获取的Access Token;
  • expires_in:Access Token的有效期,以秒为单位;
  • refresh_token:用于刷新Access Token 的 Refresh Token,长期有效,不会过期;
  • scope:Access Token最终的访问范围,既用户实际授予的权限列表(用户在授权页面时,有可能会取消掉某些请求的权限)。关于权限的具体信息请参考权限列表

[编辑] 使用Access Token

获得Access Token后,可以Access Token调用REST API。详细信息请浏览REST API以及使用Access Token调用REST API

[编辑] 刷新Access Token

Access Token生命周期较短,在某些场景下,应用需求的Access Token的生命期超过一个Access Token的生命期,就可以使用Refresh Token来刷新Access Token,Refresh Token是一个不过期的Token。

刷新Access Token需要使用HTTP POST请求人人OAuth 2.0的Access Token Endpoint,并需要带上一系列需要的参数:

  • grant_type:使用Refresh Token刷新Access Token时,此值为“refresh_token”。
  • refresh_token:获取Access Token时,同时下发的Refresh Token
  • client_id:在开发者中心注册应用时获得的API Key;
  • client_secret:在开发者中心注册应用时获得的Secret Key。此值不要嵌入到任何要发布到服务端以外的代码里(这种场景应该使用客户端流程);

注意:人人OAuth2.0支持多种传递“client_id”和“client_secret”的方式,包括:URI Query Parameter、Form-Encoded Body Parameter和RFC2617定义的HTTP Basic Authentication,详细信息请浏览Client Authenticated

请求如下:

https://graph.renren.com/oauth/token? grant_type=refresh_token& refresh_token=...& client_id=...& client_secret=...

如果应用验证通过,并且Refresh Token也正确,人人OAuth 2.0会返回Access Token相关的信息:

{ "access_token": "10000|5.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-222209506", "expires_in": 87063, "refresh_token": "10000|0.385d55f8615fdfd9edb7c4b5ebdc3e39-222209506", "scope": "read_user_album read_user_feed"}
  • access_token:获取的Access Token;
  • expires_in:Access Token的有效期,以秒为单位;
  • refresh_token:用于刷新Access Token 的 Refresh Token,长期有效,不会过期;
  • scope:Access Token最终的访问范围,既用户实际授予的权限列表(用户在授权页面时,有可能会取消掉某些请求的权限)。关于权限的具体信息请参考权限列表

[编辑] 公共主页登录

每一个公共主页都有若干个管理员,只有公共主页的管理员授予应用'admin_page'权限,应用才能以管理员的身份管理公共主页(发状态、上传照片等):

https://graph.renren.com/oauth/authorize? client_id=YOUR_API_KEY&redirect_uri=YOUR_CALLBACK_URL&scope=admin_page& response_type=token

管理员授予应用权限后,应用可以使用管理员的Access Token调用公共主页类API

[编辑] 应用类型

人人网开放平台提供了上述的OAuth 2.0验证与授权流程以支持不同类型的应用,包括:网站站内应用手机客户端桌面客户端

[编辑] 网站

网站接入开发攻略详细介绍了如何使用OAuth 2.0在网站上实现登录和账号绑定。

[编辑] 站内应用

站内应用开发攻略详细介绍了如何使用OAuth 2.0开发弹层授权,以及集成应用到人人网的开发经验。

[编辑] 手机客户端

手机客户端开发攻略详细介绍了如何使用OAuth 2.0在手机上实现登录和账号绑定,同时也介绍了在手机上实现单点登录的SSO API的使用。

[编辑] 桌面客户端

由于OAuth 2.0协议定义的桌面客户端的授权流程,用户体验方面过于复杂,所以桌面客户端应用可以在应用中嵌入浏览器控件(很多框架都支持嵌入浏览器,例如:.NET、AIR、Cocoa等)使用客户端流程。

由于大部分桌面客户端软件是没有后端没有Web服务器支持,没办法提供一个'redirect_uri',所以人人网为没有Web服务器的客户端应用提供了一个通用的URL:http://graph.renren.com/oauth/login_success.html。

流程如下:

  • 在应用中嵌入一个浏览器控件,并使用客户端流程定向控件到人人OAuth 2.0 Authorize Endpoint(https://graph.renren.com/oauth/authorize):
https://graph.renren.com/oauth/authorize? client_id=YOUR_API_KEY& redirect_uri=http://graph.renren.com/oauth/login_success.html
  • 经过用户验证、应用授权,人人OAuth 2.0将把浏览器控件定向导'redirect_uri'(http://graph.renren.com/oauth/login_success.html),并在URI Fragment中追加Access Token:
http://graph.renren.com/oauth/login_success.html#access_token=...
  • 当应用发现浏览器的控件的URL跳转到这个URL上时,从URL中解析出Access Token。

[编辑] 安全考虑

[编辑] 跨站请求伪造 (CSRF)

CSRF通过伪装来自受信任用户的请求来利用受信任的网站。为了防止CSRF攻击,在请求人人OAuth 2.0 Authorize Endpoint的时候,需要使用state传递一个用户的唯一标示,这个标示在调转到rediret_uri时会被原样返回。人人网强烈推荐使用这种方式来保持用于的状态,防止CSRF攻击。

[编辑] Redirect_URI

应用指定的'redirect_uri'不要返回HTTP 302,既不要跳转。详细信息请参考OAuth 2.0协议第十章第十五节