第三方登录——百度为例

Web网站接入

百度OAuth2.0:

  • OAuth2.0(开放授权)是一个开放标准,用户授权后,第三方应用无需获取用户的用户名和密码就可以访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表)。
  • Access Token:用户身份验证和授权的凭证。第三方应用在调用百度开放API之前,首先需要获取Access Token。

1. 授权准备:

  1. 首先成为百度用户
  2. 创建一个应用以获取API Key(client_id)和Secret Key(client_secret)

2. 支持的OAuth授权:

  目前,百度OAuth2.0支持五种获取Access Token的流程和一种刷新获取AccessToken方式,第三方可根据需求选取合适的方式:

  百度授权的Access Token是有有效期的,这样会影响用户的体验和增加开发者的工作。所以平台提供了一种方式可以保证授权有效期为永久。

  • 实现方式:返回给第三方一个月有效期的Access Token + 十年有效期的Refresh Token。
  • 实现原理:Refresh Token的作用就是在Token有效期截止前,刷新以获取新的Access Token。
获取途径授权流程介绍有效期
新获取 Authorization Code 又称Web Server Flow,适用于所有有Server端配合的应用。 有效期一个月的Access Token+有效期十年的Refresh Token。
Implicit Grant 又称User-Agent Flow,适用于所有无Server端配合的应用(桌面客户端需要内嵌浏览器)。 有效期一个月的Access Token。
Client Credentials 即采用应用公钥、密钥获取Access Token,适用于任何带server类型应用。 通过此授权方式获取Access Token仅可访问平台授权类的接口。 有效期一个月的Access Token+有效期十年的Refresh Token。
Device 适用于一些输入受限的设备上(如只有数码液晶显示屏的打印机、电视机等)。 有效期一个月的Access Token+有效期十年的Refresh Token。
刷新 Refresh Token Access Token刷新方式,适用于所有有Server端配合的应用 。 十年刷新期限。

3. 授权展示方式:

  请求用户授权时百度提供了一个在OAuth2.0协议中没有提到的参数:display。它是用来标识不同形式的客户端所对应的不同展现形式的授权页面,其值定义如下

  • page:全屏形式的授权页面(默认),适用于web应用。
  • popup: 弹框形式的授权页面,适用于桌面软件应用和web应用。
  • dialog:浮层形式的授权页面,只能用于站内web应用。
  • mobile: Iphone/Android等智能移动终端上用的授权页面,适用于Iphone/Android等智能移动终端上的应用。
  • tv: 电视等超大显示屏使用的授权页面。
  • pad: IPad/Android等智能平板电脑使用的授权页面。

4. 授权回调地址:

  为确保验证授权过程的安全,开发者必须在开发者中心预先注册应用所在的域名或URL,用以OAuth2.0检验授权请求中的“redirect_uri”参数。以便保证OAuth2.0在回调过程中,会回调到安全域名。

  • 站外有Web Server应用
    • Web应用 
    • 有Web Server支持的非Web应用(例如:有Web Server支持的手机客户端、桌面客户端应用) 。

  开发者在开发者中心的安全设置中填写了授权回调地址(支持至多十个授权回调地址)。

  • 站外无Web Server应用
    • 桌面客户端应用 
    • 手机客户端应用 
    • 基于浏览器脚本语言的应用(JavaScript、Flash、ActionScript)

  平台提供了一种默认的redirect uri参数为 "oob",回调后会返回一个平台提供默认回调地址(http://openapi.baidu.com/oauth/2.0/login_success )。

5. 权限列表:        

 
用户授权相关的权限描述
basic 用户基本权限,可以获取用户的基本信息
super_msg 往用户的百度首页上发送消息提醒,相关API任何应用都能使用,但要想将消息提醒在百度首页显示,需要第三方在注册应用时额外填写相关信息
netdisk 获取用户在个人云存储中存放的数据
平台授权相关的权限描述
public 可以访问公共的Open API
hao123 可以访问Hao123 提供的Open API接口

        每一个Access Token代表“一个用户”或“百度开放平台”授予“一个应用”的“一系列数据访问操作权限”。这“一系列数据访问操作权限”中包含默认访问权限,以及在获取Access Token过程中传递的“scope”参数所表示的扩展权限。在调用API时,百度Open API服务会检验请求中的Access Token或Session Key是否包含本API需要的权限。

        应用在请求获取Access Token时所传递的“scope”参数中可以不包含basic权限(即默认权限),一旦用户或平台同意授权,则basic权限会自动授予。百度目前开放的Open API还为数不多,目前唯一定义的扩展权限就super_msg访问权限,应用需要这个权限时需要在获取Access Token时指定scope=super_msg,如:

https://openapi.baidu.com/oauth/2.0/authorize?
    response_type=code&
    client_id=Va5yQRHlA4Fq4eR3LT0vuXV4&
    redirect_uri=http%3A%2F%2Fwww.example.com%2Foauth_redirect&
    scope=super_msg&
    display=popup

接入方案:

  第三方Web网站接入百度,主要有两种技术方案:

  1. 一种是直接使用百度连接开放平台提供的各种 Open API2.0接口,如用作验证和授权的 OAuth 2.0,提供数据的底层 Open API2.0
  2. 另一种是使用百度连接开放平台官方封装的JavaScript SDK。

接入教程:

  1. 用户授权,获取access token
  2. 调用Open API2.0获取用户信息

1.用户授权,获取access token

     采用Authorization Code获取Access Token的授权验证流程又被称为Web Server Flow,适用于所有有Server端的应用,如Web/Wap站点、有Server端的手机/桌面客户端应用等。其流程示意图如下:

    对于应用而言,其流程由以下两步组成:

      (1)获取Authorization Code

      (2)通过Authorization Code获取Access Token

1.1 获取Authorization Code

  请求数据包格式:

      其获取方式是通过重定向用户浏览器(或手机/桌面应用中的浏览器组件)到“https://openapi.baidu.com/oauth/2.0/authorize”地址上,并带上以下参数:

  • client_id:必须参数,注册应用时获得的API Key。
  • response_type:必须参数,此值固定为“code”。
  • redirect_uri:必须参数,授权后要回调的URI,即接收Authorization Code的URI
  • scope:非必须参数,以空格分隔的权限列表,若不传递此参数,代表请求用户的默认权限。关于权限的具体信息请参考“权限列表”。
  • state:非必须参数,用于保持请求和回调的状态,授权服务器在回调时(重定向用户浏览器到“redirect_uri”时),会在Query Parameter中原样回传该参数。
  • display:非必须参数,登录和授权页面的展现样式,默认为“page”,

  例如:“client_id”为“Va5yQRHlA4Fq4eR3LT0vuXV4”的应用要请求某个用户的默认权限和email访问权限,并在授权后需跳转到“http://www.example.com/oauth_redirect”,同时希望在弹出窗口中展现用户登录、授权界面,则应用需要重定向用户的浏览器到如下URL:

https://openapi.baidu.com/oauth/2.0/authorize?
    response_type=code&
    client_id=Va5yQRHlA4Fq4eR3LT0vuXV4&
    redirect_uri=http%3A%2F%2Fwww.example.com%2Foauth_redirect&
    scope=email&
    display=popup

  响应数据包格式:

  此时授权服务会根据应用传递参数的不同,为用户展现不同的授权页面。如果用户在此页面同意授权,授权服务则将重定向用户浏览器到应用所指定的“redirect_uri”,并附带上表示授权服务所分配的Authorization Code的code参数,以及state参数(如果请求authorization code时带了这个参数)。

  例如:继续上面的例子,假设授权服务在用户同意授权后生成的Authorization Code为“ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn”,则授权服务将会返回如下响应包以重定向用户浏览器到“http://www.example.com/oauth_redirect”地址上:

HTTP/1.1 302 Found
Location: http://www.example.com/oauth_redirect?code=ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn

 “code”参数可以在“redirect_uri”对应的应用后端程序中获取。 注意:每一个Authorization Code的有效期为10分钟,并且只能使用一次,再次使用将无效。

1.2 使用Authorization Code换取Access Token

    通过上面第一步获得Authorization Code后,便可以用其换取一个Access Token。获取方式是,应用在其服务端程序中发送请求(推荐使用POST)到 百度OAuth2.0授权服务的“https://openapi.baidu.com/oauth/2.0/token”地址上,并带上以下5个必须参数:

  • grant_type:必须参数,此值固定为“authorization_code”;
  • code:必须参数,通过上面第一步所获得的Authorization Code;
  • client_id:必须参数,应用的API Key;
  • client_secret:必须参数,'应用的Secret Key;
  • redirect_uri:必须参数,该值必须与获取Authorization Code时传递的“redirect_uri”保持一致。

        例如:

https://openapi.baidu.com/oauth/2.0/token?
    grant_type=authorization_code&
    code=ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn&
    client_id=Va5yQRHlA4Fq4eR3LT0vuXV4&
    client_secret=0rDSjzQ20XUj5itV7WRtznPQSzr5pVw2&
    redirect_uri=http%3A%2F%2Fwww.example.com%2Foauth_redirect
 响应数据包格式

        若参数无误,服务器将返回一段JSON文本,包含以下参数:

  • access_token:要获取的Access Token;
  • expires_in:Access Token的有效期,以秒为单位;请参考“Access Token生命周期方案
  • refresh_token:用于刷新Access Token 的 Refresh Token,所有应用都会返回该参数;(10年的有效期
  • scope:Access Token最终的访问范围,即用户实际授予的权限列表(用户在授权页面时,有可能会取消掉某些请求的权限),关于权限的具体信息参考“权限列表”一节;
  • session_key:基于http调用Open API时所需要的Session Key,其有效期与Access Token一致;
  • session_secret:基于http调用Open API时计算参数签名用的签名密钥。

        例如:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
 
{
    "access_token": "1.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-2346678-124328",
    "expires_in": 86400,
    "refresh_token": "2.385d55f8615fdfd9edb7c4b5ebdc3e39.604800.1293440400-2346678-124328",
    "scope": "basic email",
    "session_key": "ANXxSNjwQDugf8615OnqeikRMu2bKaXCdlLxn",
    "session_secret": "248APxvxjCZ0VEC43EYrvxqaK4oZExMB",
  若请求错误,服务器将返回一段JSON文本,包含以下参数:
  • error:错误码;关于错误码的详细信息请参考“百度OAuth2.0错误响应”一节。
  • error_description:错误描述信息,用来帮助理解和解决发生的错误。
   例如:
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
 
{
    "error": "invalid_grant",
    "error_description": "Invalid authorization code: ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn"
}

1.3 开发者需要注意的事项

  •  默认情况下,Access Token的有效期为永久(一个月的Access Token + 10年的Refresh Token)。关于Token方案的详细信息,请参考“Access Token生命周期方案”一节。
  • 获取Access Token时所返回的session_key和session_secret参数不是OAuth2.0协议标准规定的返回参数,而是百度OAuth2.0服务扩展加入的,目的是使得开发者可以基于http调用百度的Open API,因为基于https调用Open API虽然更为简单,但毕竟响应速度更差(比基于http的要差一倍时间左右)。

2. 调用Open API2.0获取用户信息

2.1 通过HTTPS请求调用开放API 

  通过HTTPS协议发送开放API调用请求时只需要在请求API对应的URL地址时,通过GET参数或POST参数传递具体开放API接口的业务级参数及下表中的几个系统级参数:

参数名参数类型是否必需描述
access_token string OAuth2.0验证授权后获得的token。
callback string 第三方通过JS调用开放API时可以通过指定callback参数来要求平台端返回JSONP代码,以解决跨域问题。

2.2 通过HTTPS请求调用开放API示例

  假设应用通过OAuth2.0协议获取Access Token时,授权服务器返回的JSON内容为:

{
    "access_token": "1.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-2346678-124328",
    "expires_in": 86400,
    "refresh_token": "2.385d55f8615fdfd9edb7c4b5ebdc3e39.604800.1293440400-2346678-124328",
    "scope": "basic email",
    "session_key": "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A=",
    "session_secret": "27e1be4fdcaa83d7f61c489994ff6ed6",
}

  当前系统时间为2011-06-21 17:18:09,要求以json格式返回API调用结果,则应用既可以通过GET方法发送如下请求包来调用获取当前登录用户的基本资料的开放API接口:

GET https://openapi.baidu.com/rest/2.0/passport/users/getInfo?access_token=1.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-2346678-124328 HTTP/1.1
Host: openapi.baidu.com
User-Agent: Client of Baidu Open Platform
Accept: */*
Accept-Encoding: gzip,deflate
Accept-Charset: utf-8
Connection: close

  也可以通过POST方法发送如下请求包,来获取开放API调用的响应结果。

POST https://openapi.baidu.com/rest/2.0/passport/users/getInfo HTTP/1.1
Host: openapi.baidu.com
User-Agent: Client of Baidu Open Platform
Accept: */*
Accept-Encoding: gzip,deflate
Accept-Charset: utf-8
Content-Length: 91
Connection: close
 
access_token=1.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-2346678-124328

2.3 开放API调用的响应结果

2.3.1 正常响应结果

      请参考每个具体开放API的详细说明文档

2.3.2 异常响应结果

  由于每个API调用都是通过发送HTTP请求或HTTPS来完成的,因此都有可能因为发送的参数不合法、发送频率过快次数过多、平台REST服务自身出问题等原因而导致API调用失败,此时百度REST服务器将按照format参数所指定的响应格式返回相应错误信息,包含如下参数:

  • error_code: 错误码,查看所有错误码定义请参考[常见错误码说明];
  • error_msg: 对调用失败原因的描述。

2.3.3 开放API调用的响应结果示例

      (百度API列表见  http://developer.baidu.com/wiki/index.php?title=docs/oauth/rest/file_data_apis_list)

  以调用获取当前登录用户基本资料的API接口为例,假设通过https请求发送API调用请求时所传递的access_token已经过期。 则将返回如下格式的错误信息:

{
    "error_code": "110",
    "error_msg": "Access token invalid or no longer valid",
}

 2.4 百度Open API错误码定义:

(参考:http://developer.baidu.com/wiki/index.php?title=%E7%99%BE%E5%BA%A6Open_API%E9%94%99%E8%AF%AF%E7%A0%81%E5%AE%9A%E4%B9%89)

Error CodeError Description(Chinese)Error Description(English)
0 成功 Success
1 未知错误 Unknown error
2 服务暂不可用 Service temporarily unavailable
3 未知的方法 Unsupported openapi method
4 接口调用次数已达到设定的上限 Open api request limit reached
5 请求来自未经授权的IP地址 Unauthorized client IP address:%s
6 无权限访问该用户数据 No permission to access data
7 来自该refer的请求无访问权限 No permission to access data for this referer
100 请求参数无效 Invalid parameter
101 api key无效 Invalid API key
102 session key无效 Session key invalid or no longer valid
103 call_id参数无效 Invalid/Used call_id parameter
104 无效签名 Incorrect signature
105 请求参数过多 Too many parameters
106 未知的签名方法 Unsupported signature method
107 timestamp参数无效 Invalid/Used timestamp parameter
108 无效的user id Invalid user id
109 无效的用户资料字段名 Invalid user info field
110 无效的access token Access token invalid or no longer valid
111 access token过期 Access token expired
112 session key过期 Session key expired
114 无效的ip参数 Invalid Ip
210 用户不可见 User not visible
211 获取未授权的字段 Unsupported permission
212 没有权限获取用户的email No permission to access user email
800 未知的存储操作错误 Unknown data store API error
801 无效的操作方法 Invalid operation
802 数据存储空间已超过设定的上限 Data store allowable quota was exceeded
803 指定的对象不存在 Specified object cannot be found
804 指定的对象已存在 Specified object already exists
805 数据库操作出错,请重试 A database error occurred. Please try again
900 访问的应用不存在 No such application exists
950 批量操作已开始,请先调用end_batch接口结束前一个批量操作 begin_batch already called, please make sure to call end_batch first
951 结束批量操作的接口调用不应该在start_batch接口之前被调用 end_batch called before start_batch
952 每个批量调用不能包含多于20个接口调用 Each batch API can not contain more than 20 items
953 该接口不适合在批量调用操作中被使用 Method is not allowed in batch mode

参考文档:http://developer.baidu.com/wiki/index.php?title=%E5%B8%AE%E5%8A%A9%E6%96%87%E6%A1%A3%E9%A6%96%E9%A1%B5/%E7%99%BE%E5%BA%A6%E5%B8%90%E5%8F%B7%E8%BF%9E%E6%8E%A5

原文地址:https://www.cnblogs.com/sheropan/p/5070016.html