baidu-sdk 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 989e658f22320158d197a3dcad2a2bb02fd2bae0
4
- data.tar.gz: 386a4d15d1237e93b6081d90c678328b6728774f
3
+ metadata.gz: e7d739a156a7feec33727249033320452ff730d1
4
+ data.tar.gz: 1db71954fe27d31241176786cab6ec5dbd18ae09
5
5
  SHA512:
6
- metadata.gz: d1a83fcbeb4bd8eba7ebf195f2f9a62742be6271187288fbd346ed7e6dae040c343658760cc2230da600dd019ec681c848b4482307ca684e7a80667ae6c04d1e
7
- data.tar.gz: cd3a8c489b63b9796988fadf59187825fbdf0d6eff4c4ba20f62863de57c622e636f8efa684e513ff978af847c320902505374a2de892479887e34aacffb4f39
6
+ metadata.gz: 7ea790ba81dabc1968e53664a95e30b741ba1d9c282d4631edeac230b9b2c9e631d359add53badf7636e7acda6dfff7f924ccf98ceeced42b166627766d9afe7
7
+ data.tar.gz: 19e130371ed9e9d9f804b0fbf60e1e6a6e4dc5c9df7f1b50e715cd3152b404c942a1594202194a8dd1e1b775c16bf6e74d126cb55b40bbbfeeaf8e690eab4780
data/HISTORY.md CHANGED
@@ -1,2 +1,7 @@
1
+ ## 0.0.2 (2013-12-06)
2
+ * **OAuth** 添加 Implicit Grant 授权流程
3
+ * **OAuth** 添加 Client Credentials 授权流程
4
+ * **OAuth** API 修改:Client#code_flow => Client#authorization_code_flow
5
+
1
6
  ## 0.0.1 (2013-11-28)
2
7
  * 首个版本
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Baidu SDK for Ruby [![Build Status](https://travis-ci.org/lonre/baidu-sdk-ruby.png?branch=master)](https://travis-ci.org/lonre/baidu-sdk-ruby)
2
2
 
3
3
  Unofficial Baidu REST API SDK for Ruby.
4
+
4
5
  非官方百度开放接口 Ruby 开发包。
5
6
 
6
7
  ## 安装
@@ -26,10 +27,14 @@ Unofficial Baidu REST API SDK for Ruby.
26
27
 
27
28
  `Hash` 必须使用 `symbol` key,无论是返回值或作为参数传递给方法。
28
29
 
29
- 涉及到调用 Baidu REST API 并返回 Hash 时,除非特别说明,Hash 是在原始 API 返回的 JSON 结果之上 `parse(JSON.parse(resp.body, symbolize_names: true))` 而来,Hash 和 JSON 拥有相同的结构,返回的具体结构可以参考各个方法的 API Doc。如:
30
+ 涉及到调用 Baidu REST API 并返回 Hash 时,此 Hash 返回值是在原始 API 返回的 JSON 数据之上 `parse(JSON.parse(resp.body, symbolize_names: true))` 而来。(特别说明返回值的除外,如:`Baidu::OAuth::Flow::Code#get_token` 返回 `Baidu::Session`)。Hash 和 JSON 拥有相同的结构,返回的具体结构可以参考各个方法的 API Doc。如:
31
+
30
32
  ```ruby
31
33
  # 返回的原始 JSON
32
34
  # {"quota":15000000000,"used":5221166,"request_id":4043312634}
35
+ #
36
+ # result 是转换 JSON 后得到的 Hash
37
+ # {:quota=>15000000000, :used=>5221166, :request_id=>4043312634}
33
38
  result = pcs_client.quota
34
39
  result[:quota] # => 15000000000
35
40
  result[:used] # => 5221166
@@ -39,6 +44,7 @@ result[:used] # => 5221166
39
44
  首先确保已经在百度开发者中心创建了应用。如果还没有创建应用,请通过此链接 [百度开发者中心](http://developer.baidu.com/console) 创建一个新的应用,获取应用的 `API Key` 和 `Secret Key`。
40
45
 
41
46
  1. 使用全局配置方式:
47
+
42
48
  ```ruby
43
49
  Baidu.config do |c|
44
50
  c.client_id = 'an_api_key'
@@ -48,31 +54,64 @@ result[:used] # => 5221166
48
54
  此全局配置为可选方式,还可以在新建 `Baidu::OAuth::Client` 实例的时候指定 `API Key` 和 `Secret Key`。
49
55
 
50
56
  2. 创建 Baidu::OAuth::Client 实例
57
+
58
+ 首先,加载 `oauth` 库
59
+
51
60
  ```ruby
52
61
  require 'baidu/oauth'
62
+ ```
63
+ 其次,创建实例
64
+
65
+ ```ruby
53
66
  client = Baidu::OAuth::Client.new
54
- # 或者
67
+ # 或如下,为实例指定 client_id, client_secret
55
68
  client = Baidu::OAuth::Client.new('a_client_id', 'a_client_secret')
56
69
  ```
57
70
  后者创建的实例受全局配置影响
58
- 3. Baidu OAuth 有四种(当前实现两种)获取 Access Token 的方式,包括 `Authorization Code`, `Implicit Grant`, `Client Credentials`, `Device`以及一个刷新方式`Refresh Token`
71
+
72
+ 3. Baidu OAuth 有四种获取 Access Token 的方式,包括 `Authorization Code`, `Implicit Grant`, `Client Credentials`, `Device`以及一个刷新方式`Refresh Token`
59
73
 
60
74
  ```ruby
61
- client.code_flow.authorize_url # 使用 Authorization Code 授权流程
62
- client.code_flow.get_token # 使用 Authorization Code 授权流程
63
- client.device_flow.user_and_device_code # 使用 Device 授权流程
64
- client.device_flow.get_token # 使用 Device 授权流程
65
- client.refresh # Access Token刷新方式
75
+ # 使用 Authorization Code 授权流程,获取 Authorization URL
76
+ client.authorization_code_flow.authorize_url('callback_uri')
77
+
78
+ # 使用 Authorization Code 授权流程,获取 Access Token(Baidu::Session)
79
+ client.authorization_code_flow.get_token('code', 'callback_uri')
80
+
81
+ # 使用 Device 授权流程,获取 User Code 和 Device Code
82
+ client.device_flow.user_and_device_code
83
+
84
+ # 使用 Device 授权流程,获取 Access Token(Baidu::Session)
85
+ client.device_flow.get_token('code')
86
+
87
+ # 使用 Implicit Grant 授权流程
88
+ client.implicit_grant_flow.authorize_url('callback_uri')
89
+
90
+ # 使用 Implicit Grant 授权流程授权后,
91
+ # 客户端解析 callback_uri 中 Fragment 所携带参数获取 Access Token
92
+ # http://localhost:4567/auth/callback#expires_in=2592000&access_token=3.c79b45...
93
+
94
+ # 使用 Client Credentials 授权流程获取 Access Token
95
+ client.client_credentials_flow.get_token
96
+
97
+ # 刷新并获取新的 Access Token(Baidu::Session),所有流程均适用
98
+ client.refresh('refresh_token')
66
99
  ```
67
- 4. `Baidu::Session` 包含授权信息
100
+
101
+ 4. `Baidu::Session` 授权信息
102
+
103
+ 所有 `get_token` 及 `refresh` 均返回 `Baidu::Session`,包含授权信息,如:
68
104
 
69
105
  ```ruby
70
- session = client.code_flow.get_token
71
- session = client.device_flow.get_token
72
- ...
106
+ session = client.device_flow.get_token('code')
107
+ puts session.access_token
108
+ puts session.refresh_token
109
+ puts session.scope
110
+ puts session.session_key
111
+ puts session.session_secret
73
112
  ```
74
113
 
75
- ### Authorization Code 授权流程示例:
114
+ ### Sinatra Authorization Code 授权简单示例
76
115
 
77
116
  ```ruby
78
117
  # 1. Edit and save this snippet as code.rb
@@ -96,13 +135,13 @@ end
96
135
 
97
136
  get '/auth' do
98
137
  client = Baidu::OAuth::Client.new
99
- redirect client.code_flow.authorize_url(callback_uri, confirm_login: true)
138
+ redirect client.authorization_code_flow.authorize_url(callback_uri, confirm_login: true)
100
139
  end
101
140
 
102
141
  get '/auth/callback' do
103
142
  begin
104
143
  client = Baidu::OAuth::Client.new
105
- session = client.code_flow.get_token params[:code], callback_uri
144
+ session = client.authorization_code_flow.get_token params[:code], callback_uri
106
145
  "auth success: #{session.access_token}"
107
146
  rescue => e
108
147
  e.to_s
@@ -113,9 +152,12 @@ end
113
152
  ## PCS
114
153
  要使用 PCS 必须到 [百度开发者中心](http://developer.baidu.com/console) 开启指定应用的 PCS API 权限,参考 [开通PCS API权限](http://developer.baidu.com/wiki/index.php?title=docs/pcs/guide/api_approve),并获取所设置的文件目录。
115
154
 
116
- 文件 API 已经完全实现。API 中涉及到的文件或目录路径,都是相对于开通 PCS API 权限时所设置的文件目录。比如:上传文件时需要指定文件保存路径,假设指定为 `/mydata/hi.png`,那么在 PCS 中实际的保存路径为 `/apps/文件目录/mydata/hi.png`。
155
+ PCS 服务 API 包括文件 API 以及结构化数据 API,目前已经实现全部文件 API。
156
+
157
+ **API 中涉及到的文件或目录路径,都是相对于开通 PCS API 权限时所设置的文件目录**。比如:上传文件时需要指定文件保存路径,假设指定为 `/mydata/hi.png`,那么在 PCS 中实际的保存路径为 `/apps/文件目录/mydata/hi.png`。
117
158
 
118
159
  1. 全局配置
160
+
119
161
  ```ruby
120
162
  Baidu.config do |c|
121
163
  # ...
@@ -126,14 +168,22 @@ end
126
168
  全局配置非强制性的,可以在创建 `Baidu::PCS::Client` 实例时设置
127
169
 
128
170
  2. 创建 Baidu::PCS::Client 实例
171
+
172
+ 首先,加载 `pcs` 库
173
+
129
174
  ```ruby
130
175
  require 'baidu/pcs'
176
+ ```
177
+ 其次,创建实例
178
+
179
+ ```ruby
131
180
  client = Baidu::PCS::Client.new('token_or_session')
132
- # 或者
181
+ # 或如下,为实例指定文件目录
133
182
  client = Baidu::PCS::Client.new('token_or_session', 'notes')
134
183
  ```
135
184
 
136
185
  3. API 调用
186
+
137
187
  ```ruby
138
188
  File.open('/opt/ubuntu-12.04.3-server-amd64.iso', 'r') do |f|
139
189
  client.upload(f, block_upload: true)
@@ -143,11 +193,14 @@ end
143
193
  ## 异常处理
144
194
  API 的异常被封装为 `Baidu::Errors::Error`,包含三个子类:
145
195
 
146
- 1. `Baidu::Errors::AuthError` # Access Token 过期或未授权
147
- 2. `Baidu::Errors::ClientError` # API 返回 `400+` 错误
148
- 3. `Baidu::Errors::ServerError` # API 返回 `500+` 错误
196
+ ```
197
+ 1. Baidu::Errors::AuthError # 未授权或 Access Token 过期
198
+ 2. Baidu::Errors::ClientError # API 返回 400+ 错误
199
+ 3. Baidu::Errors::ServerError # API 返回 500+ 错误
200
+ ```
149
201
 
150
202
  `Baidu::Errors::Error => e`,异常的具体信息可以通过如下方式获取到:
203
+
151
204
  ```ruby
152
205
  begin
153
206
  client.list('apitest/movies')
data/lib/baidu/oauth.rb CHANGED
@@ -6,6 +6,7 @@ module Baidu
6
6
  SITE = 'https://openapi.baidu.com'
7
7
  AUTHORIZATION_ENDPOINT = '/oauth/2.0/authorize'
8
8
  TOKEN_ENDPOINT = '/oauth/2.0/token'
9
+ TOKEN_INFO_ENDPOINT = '/oauth/2.0/tokeninfo'
9
10
  DEVICE_ENDPOINT = '/oauth/2.0/device/code'
10
11
  end
11
12
  end
@@ -1,7 +1,9 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'baidu/oauth/flow/code'
3
+ require 'baidu/oauth/flow/authorization_code'
4
4
  require 'baidu/oauth/flow/device'
5
+ require 'baidu/oauth/flow/implicit_grant'
6
+ require 'baidu/oauth/flow/client_credentials'
5
7
 
6
8
  module Baidu
7
9
  module OAuth
@@ -27,17 +29,30 @@ module Baidu
27
29
  @site = Baidu::OAuth::SITE
28
30
  end
29
31
 
30
- # @!method code_flow
32
+ # @!method authorization_code_flow
31
33
  # 采用 Authorization Code 获取 Access Token 的授权验证流程
32
- # @return [Flow::Code]
34
+ # @return [Flow::AuthorizationCode]
35
+ #
33
36
  # @!method device_flow
34
37
  # 采用 Device Code 获取 Access Token 的授权验证流程
35
38
  # @return [Flow::Device]
36
- # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/authorization Authorization Code
37
- # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device Device
38
- [:code, :device].each do |flow|
39
+ #
40
+ # @!method implicit_grant_flow
41
+ # 采用 Implicit Grant 方式获取 Access Token 的授权验证流程
42
+ # @return [Flow::ImplicitGrant]
43
+ #
44
+ # @!method client_credentials_flow
45
+ # 使用 Client Credentials 获取 Access Token 的授权验证流程
46
+ # @return [Flow::ClientCredentials]
47
+ #
48
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/authorization Authorization Code 授权
49
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device Device 授权
50
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/implicit Implicit Grant 授权
51
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/client Client Credentials 授权
52
+ [:authorization_code, :device, :implicit_grant, :client_credentials].each do |flow|
39
53
  define_method("#{flow}_flow".to_sym) do
40
- Baidu::OAuth::Flow.const_get(flow.capitalize).new self
54
+ klass_name = flow.to_s.split('_').map { |s| s.capitalize }.join
55
+ Baidu::OAuth::Flow.const_get(klass_name).new self
41
56
  end
42
57
  end
43
58
 
@@ -61,6 +76,34 @@ module Baidu
61
76
  return nil if rest.nil?
62
77
  Baidu::Session.from rest
63
78
  end
79
+
80
+ # 查询Access Token对应的授权信息
81
+ #
82
+ # 该接口用于查询Access Token对应的授权相关信息,
83
+ # 包括授权对象(应用)、授权用户、授权的权限、授权时间,过期时间。
84
+ # @example 返回的原始 JSON
85
+ # {
86
+ # "client_id": "ZLycGmiUcCkrSb3t7zSD8uV6",
87
+ # "userid": 689911016,
88
+ # "scope": "basic super_msg",
89
+ # "create_time": 1364555477,
90
+ # "expire_in": 2591980
91
+ # }
92
+ #
93
+ # :client_id Access Token对应应用的Api Key
94
+ # :userid 授权用户的唯一id。如果Access Token是通过Client Credentials授权方式 获取的,则该字段值为0
95
+ # :scope Access Token最终的访问范围,即用户实际授予的权限列表(用户在授权页面时,有可能会取消掉某些请求的权限)
96
+ # :create_time Access Token的生成时间(Unix时间戳),以秒为单位
97
+ # :expires_in Access Token剩余的有效时间,以秒为单位
98
+ #
99
+ # @param [String] access_token 授权之后应用得到的Access Token
100
+ # @return [Hash]
101
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/tokeninfo 校验Access Token
102
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/list 权限列表
103
+ def token_info(access_token)
104
+ body = { access_token: access_token }
105
+ return post Baidu::OAuth::TOKEN_INFO_ENDPOINT, nil, body
106
+ end
64
107
  end
65
108
  end
66
109
  end
@@ -10,20 +10,21 @@ module Baidu
10
10
  # 适用于所有有Server端的应用,如Web/Wap站点、有Server端的手机/桌面客户端应用等。
11
11
  #
12
12
  # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/authorization Authorization Code授权
13
- class Code
14
- include Base
13
+ class AuthorizationCode < Base
14
+ include Authable
15
+ include Tokenable
15
16
 
16
- # 通过 Device Code 来获取 Access Token
17
+ # 通过获得的 Authorization Code,换取一个 Access Token
17
18
  #
18
19
  # @note 每一个 Authorization Code 的有效期为10分钟,并且只能使用一次,再次使用将无效。
19
20
  #
20
21
  # 如果用户在此页面同意授权,授权服务则将重定向用户浏览器到应用所指定的“redirect_uri”,
21
22
  # 并附带上表示授权服务所分配的 Authorization Code 的 +code+ 参数,以及 state 参数(如果请求authorization code时带了这个参数)。
22
23
  #
23
- # @param [String] code 所获得的 Authorization Code (redirect_uri 附带的 {code} 参数)
24
+ # @param [String] code 所获得的 Authorization Code (redirect_uri 附带的 code 参数)
25
+ # @param [String] redirect_uri 该值必须与获取 Authorization Code 时传递的 “redirect_uri” 保持一致
24
26
  # @return [Baidu::Session]
25
- # @see #user_and_device_code
26
- # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device 通过Device Code获取Access Token
27
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/authorization Authorization Code授权
27
28
  # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/overview Access Token生命周期
28
29
  def get_token(code, redirect_uri); super end
29
30
 
@@ -44,15 +45,11 @@ module Baidu
44
45
  # @option params [Boolean] :force_login +true+ 表示加载登录页时强制用户输入用户名和口令,不会从cookie中读取百度用户的登陆状态
45
46
  # @option params [Boolean] :confirm_login +true+ 表示且百度用户已处于登陆状态,会提示是否使用已当前登陆用户对应用授权
46
47
  # @return [String]
48
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/authorization Authorization Code授权
47
49
  # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/list 权限列表
48
50
  # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/set 页面设置
49
51
  # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/redirect 授权回调地址
50
- def authorize_url(redirect_uri, params={})
51
- opts = {}.update(params)
52
- opts.update({ force_login: 1 }) if params[:force_login]
53
- opts.update({ confirm_login: 1 }) if params[:confirm_login]
54
- super redirect_uri, opts
55
- end
52
+ def authorize_url(redirect_uri, params={}); super end
56
53
 
57
54
  private
58
55
 
@@ -3,26 +3,41 @@
3
3
  module Baidu
4
4
  module OAuth
5
5
  module Flow
6
- module Base
7
- include Baidu::Support
6
+
7
+ # 所有授权流程基类
8
+ class Base
8
9
 
9
10
  # 此授权流程对应的 OAuth Client 实例
11
+ # @return [Baidu::OAuth::Client]
10
12
  attr_reader :client
11
13
 
12
14
  def initialize(client)
13
15
  @client = client
14
16
  end
17
+ end
18
+
19
+ # @private
20
+ module Authable
21
+ include Baidu::Support
15
22
 
23
+ # Sub class must implement +authorize_query+ method
16
24
  def authorize_url(redirect_uri, params={})
17
25
  query = authorize_query.update params
18
26
  query.update({ client_id: self.client.client_id, redirect_uri: redirect_uri })
27
+ query.update({ force_login: 1 }) if params[:force_login]
28
+ query.update({ confirm_login: 1 }) if params[:confirm_login]
19
29
  Util.clean_params query
20
30
  uri = URI(self.client.site)
21
- uri.path = authorize_endpoint
31
+ uri.path = Baidu::OAuth::AUTHORIZATION_ENDPOINT
22
32
  uri.query = Util.encode_params(query) unless Util.blank? query
23
33
  uri.to_s
24
34
  end
35
+ end
36
+
37
+ # @private
38
+ module Tokenable
25
39
 
40
+ # Sub class must implement +token_body+ method
26
41
  def get_token(code, redirect_uri=nil, params={})
27
42
  body = token_body.update params
28
43
  body.update({ client_id: self.client.client_id,
@@ -32,12 +47,6 @@ module Baidu
32
47
  return nil if rest.nil?
33
48
  Baidu::Session.from rest
34
49
  end
35
-
36
- private
37
-
38
- def authorize_endpoint
39
- Baidu::OAuth::AUTHORIZATION_ENDPOINT
40
- end
41
50
  end
42
51
  end
43
52
  end
@@ -0,0 +1,37 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'baidu/oauth/flow/base'
4
+
5
+ module Baidu
6
+ module OAuth
7
+ module Flow
8
+
9
+ # 采用Client Credentials方式,即应用公钥、密钥方式获取Access Token,
10
+ # 适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open API,
11
+ # 并且需要开发者提前向百度开放平台申请,成功对接后方能使用。
12
+ # 对于应用而言,其流程只有一步,即直接获取Access Token。
13
+ #
14
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/client Client Credentials授权
15
+ class ClientCredentials < Base
16
+ include Tokenable
17
+
18
+ # 使用 Client Credentials 获取 Access Token
19
+ #
20
+ # @param [String] scope Access Token最终的访问范围,即用户实际授予的权限列表
21
+ # @return [Baidu::Session]
22
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/client Client Credentials授权
23
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/list 权限列表
24
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/overview Access Token生命周期
25
+ def get_token(scope=nil)
26
+ super(nil, nil, scope: scope)
27
+ end
28
+
29
+ private
30
+
31
+ def token_body
32
+ { grant_type: 'client_credentials' }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -10,9 +10,10 @@ module Baidu
10
10
  # 填写User Code并授权、以及通过Device Code获取Access Token这3步组成。
11
11
  #
12
12
  # @note 使用此授权流程,对于终端类型的应用也非常方便,同时还可以获取 Refresh Token
13
+ #
13
14
  # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device Device授权
14
- class Device
15
- include Base
15
+ class Device < Base
16
+ include Tokenable
16
17
 
17
18
  # 获取 User Code 和 Device Code
18
19
  # @example 返回的原始 JSON
@@ -35,11 +36,12 @@ module Baidu
35
36
  #
36
37
  # @param [String] scope 非必须参数,以空格分隔的权限列表
37
38
  # @return [Hash]
39
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device Device授权
38
40
  # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/list 权限列表
39
41
  def user_and_device_code(scope=nil)
40
42
  query = authorize_query.update({ client_id: self.client.client_id })
41
43
  query[:scope] = scope unless scope.nil?
42
- self.client.get(authorize_endpoint, query)
44
+ self.client.get(Baidu::OAuth::DEVICE_ENDPOINT, query)
43
45
  end
44
46
 
45
47
  # 通过 Device Code 来获取 Access Token
@@ -47,15 +49,10 @@ module Baidu
47
49
  # @param [String] code {#user_and_device_code} 所获得的 Device Code
48
50
  # @return [Baidu::Session]
49
51
  # @see #user_and_device_code
50
- # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device 通过Device Code获取Access Token
52
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device Device授权
51
53
  # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/overview Access Token生命周期
52
54
  def get_token(code); super end
53
55
 
54
- # @private
55
- def authorize_url
56
- raise NoMethodError, 'no such method in device flow'
57
- end
58
-
59
56
  private
60
57
 
61
58
  def authorize_query
@@ -65,10 +62,6 @@ module Baidu
65
62
  def token_body
66
63
  { grant_type: 'device_token' }
67
64
  end
68
-
69
- def authorize_endpoint
70
- Baidu::OAuth::DEVICE_ENDPOINT
71
- end
72
65
  end
73
66
  end
74
67
  end
@@ -0,0 +1,57 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'baidu/oauth/flow/base'
4
+
5
+ module Baidu
6
+ module OAuth
7
+ module Flow
8
+
9
+ # 采用Implicit Grant方式获取Access Token的授权验证流程又被称为User-Agent Flow,
10
+ # 适用于所有无Server端配合的应用(由于应用往往位于一个User Agent里,如浏览器里面,
11
+ # 因此这类应用在某些平台下又被称为Client-Side Application),如手机/桌面客户端程序、浏览器插件等,
12
+ # 以及基于JavaScript等脚本客户端脚本语言实现的应用,他们的一个共同特点是,
13
+ # 应用无法妥善保管其应用密钥(App Secret Key)
14
+ #
15
+ # @note 采用Implicit Grant方式获取Access Token时,不会返回Refresh Token。
16
+ # @note
17
+ # 为了保证安全性,建议应用从授权回调地址接收到Access Token之后,
18
+ # 调用Access Token验证接口判断该Access Token是否对应自身的Api Key。
19
+ #
20
+ # @see Client#token_info
21
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/implicit Implicit Grant授权
22
+ class ImplicitGrant < Base
23
+ include Authable
24
+
25
+ # 获取 Authorization URL
26
+ #
27
+ # @note
28
+ # 为了加强安全性,会对跳转到该授权页面的Referer进行检测,
29
+ # 要求Referer必须与开发者创建应用时注册的"网站地址"或者在“OAuth安全设置”中所填写的"根域名绑定"同域。
30
+ #
31
+ # @param [String] redirect_uri
32
+ # 授权后要回调的URI,即接受Access Token的URI。
33
+ # 如果用户在授权过程中取消授权,会回调该URI,并在URI末尾附上error=access_denied参数。
34
+ # 对于无Web Server的应用,其值可以是“oob”,授权后会回调OAuth提供的一个默认页面。
35
+ # 如果redirect_uri不为"oob",则redirect_uri指向的页面必须与开发者在“OAuth安全设置”中所填写的"授权回调地址"相匹配。
36
+ # @option params [String] :scope 以空格分隔的权限列表,若不传递此参数,代表请求用户的默认权限
37
+ # @option params [String] :state
38
+ # 用于保持请求和回调的状态,授权服务器在回调时(重定向用户浏览器到“redirect_uri”时),会在Fragment中原样回传该参数。
39
+ # @option params [String] :display 登录和授权页面的展现样式,默认为“page”
40
+ # @option params [Boolean] :force_login +true+ 表示加载登录页时强制用户输入用户名和口令,不会从cookie中读取百度用户的登陆状态
41
+ # @option params [Boolean] :confirm_login +true+ 表示且百度用户已处于登陆状态,会提示是否使用已当前登陆用户对应用授权
42
+ # @return [String]
43
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/implicit Implicit Grant授权
44
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/list 权限列表
45
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/set 页面设置
46
+ # @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/redirect 授权回调地址
47
+ def authorize_url(redirect_uri, params={}); super end
48
+
49
+ private
50
+
51
+ def authorize_query
52
+ { response_type: 'token', display: 'page' }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/baidu/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Baidu
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
@@ -44,25 +44,38 @@ describe Baidu::OAuth::Client do
44
44
  end
45
45
 
46
46
  context '#authorize_url' do
47
- it 'generates "Authorization Code" authorize url' do
48
- url = @client.code_flow.authorize_url('oob')
49
- expect(url).to eq("#{authorization_endpoint}?response_type=code&display=page&" \
50
- "client_id=ci&redirect_uri=oob")
51
- end
47
+ context 'with code flow' do
48
+ it 'generates "Authorization Code" authorize url' do
49
+ url = @client.authorization_code_flow.authorize_url('oob')
50
+ expect(url).to eq("#{authorization_endpoint}?response_type=code&display=page&" \
51
+ "client_id=ci&redirect_uri=oob")
52
+ end
52
53
 
53
- it 'generates "Authorization Code" authorize url with params' do
54
- url = @client.code_flow.authorize_url('http://www.example.com/oauth_redirect',
55
- scope: 'email', state: 'xyz', display: 'tv',
56
- force_login: 1, confirm_login: 1)
57
- expect(url).to eq("#{authorization_endpoint}?response_type=code&display=tv&" \
58
- "scope=email&state=xyz&force_login=1&confirm_login=1&client_id=ci&" \
59
- "redirect_uri=http%3A%2F%2Fwww.example.com%2Foauth_redirect")
54
+ it 'generates "Authorization Code" authorize url with params' do
55
+ url = @client.authorization_code_flow.authorize_url('http://www.example.com/oauth_redirect',
56
+ scope: 'email', state: 'xyz', display: 'tv',
57
+ force_login: true, confirm_login: true)
58
+ expect(url).to eq("#{authorization_endpoint}?response_type=code&display=tv&" \
59
+ "scope=email&state=xyz&force_login=1&confirm_login=1&client_id=ci&" \
60
+ "redirect_uri=http%3A%2F%2Fwww.example.com%2Foauth_redirect")
61
+ end
60
62
  end
61
63
 
62
- it 'raises error when using device flow' do
63
- expect {
64
- @client.device_flow.authorize_url
65
- }.to raise_error(NoMethodError, 'no such method in device flow')
64
+ context 'with implicit flow' do
65
+ it 'generates "Implicit Grant" authorize url' do
66
+ url = @client.implicit_grant_flow.authorize_url('oob')
67
+ expect(url).to eq("#{authorization_endpoint}?response_type=token&display=page&" \
68
+ "client_id=ci&redirect_uri=oob")
69
+ end
70
+
71
+ it 'generates "Implicit Grant" authorize url with params' do
72
+ url = @client.implicit_grant_flow.authorize_url('http://www.example.com/oauth_redirect',
73
+ scope: 'basic email', state: 'xyz', display: 'mobile',
74
+ force_login: true, confirm_login: true)
75
+ expect(url).to eq("#{authorization_endpoint}?response_type=token&display=mobile&" \
76
+ "scope=basic+email&state=xyz&force_login=1&confirm_login=1&client_id=ci&" \
77
+ "redirect_uri=http%3A%2F%2Fwww.example.com%2Foauth_redirect")
78
+ end
66
79
  end
67
80
  end
68
81
 
@@ -112,7 +125,7 @@ describe Baidu::OAuth::Client do
112
125
  end
113
126
 
114
127
  it 'requests access tokey' do
115
- @client.code_flow.get_token 'ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn',
128
+ @client.authorization_code_flow.get_token 'ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn',
116
129
  'http://www.example.com/oauth_redirect'
117
130
  a_post(:oauth, '/oauth/2.0/token',
118
131
  grant_type: 'authorization_code',
@@ -122,7 +135,7 @@ describe Baidu::OAuth::Client do
122
135
  end
123
136
 
124
137
  it 'responses access token' do
125
- result = @client.code_flow.get_token 'ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn',
138
+ result = @client.authorization_code_flow.get_token 'ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn',
126
139
  'http://www.example.com/oauth_redirect'
127
140
  expect(result).to be_instance_of(Baidu::Session)
128
141
  expect(result).to respond_to(:access_token)
@@ -140,7 +153,7 @@ describe Baidu::OAuth::Client do
140
153
  to_return(status: 200, body: ft('get_token_device.json'))
141
154
  end
142
155
 
143
- it 'requests access tokey' do
156
+ it 'requests access token' do
144
157
  @client.device_flow.get_token 'a82hjs723h72h3a82hjs723h72h3vb'
145
158
  a_post(:oauth, '/oauth/2.0/token', grant_type: 'device_token',
146
159
  code: 'a82hjs723h72h3a82hjs723h72h3vb',
@@ -159,6 +172,36 @@ describe Baidu::OAuth::Client do
159
172
  end
160
173
  end
161
174
 
175
+ context 'with client credentials' do
176
+ let(:base_params) do
177
+ { grant_type: 'client_credentials', client_id: 'ci', client_secret: 'cs' }
178
+ end
179
+
180
+ it 'requests access token' do
181
+ stub = stub_post(:oauth, '/oauth/2.0/token', base_params)
182
+ @client.client_credentials_flow.get_token
183
+ stub.should have_been_requested
184
+ end
185
+
186
+ it 'requests access token with scope' do
187
+ stub = stub_post(:oauth, '/oauth/2.0/token', base_params.update({ scope: 'basic hao123' }))
188
+ @client.client_credentials_flow.get_token('basic hao123')
189
+ stub.should have_been_requested
190
+ end
191
+
192
+ it 'responses access token' do
193
+ stub = stub_post(:oauth, '/oauth/2.0/token', base_params).
194
+ to_return(status: 200, body: ft('get_token_client_credentials.json'))
195
+ result = @client.client_credentials_flow.get_token
196
+ expect(result).to be_instance_of(Baidu::Session)
197
+ expect(result).to respond_to(:access_token)
198
+ expect(result).to respond_to(:refresh_token)
199
+ expect(result).to respond_to(:scope)
200
+ expect(result).to respond_to(:session_key)
201
+ expect(result).to respond_to(:session_secret)
202
+ end
203
+ end
204
+
162
205
  context '#refresh_token' do
163
206
  before do
164
207
  stub_post(:oauth, '/oauth/2.0/token', grant_type: 'refresh_token',
@@ -196,4 +239,14 @@ describe Baidu::OAuth::Client do
196
239
  expect(result).to respond_to(:session_secret)
197
240
  end
198
241
  end
242
+
243
+ context '#token_info' do
244
+ it 'requests token info' do
245
+ stub = stub_post(:oauth, '/oauth/2.0/tokeninfo', access_token: 'xxxx').
246
+ to_return(status: 200, body: ft('token_info.json'))
247
+ rest = @client.token_info('xxxx')
248
+ stub.should have_been_requested
249
+ expect(rest).to be_instance_of(Hash)
250
+ end
251
+ end
199
252
  end
@@ -0,0 +1,8 @@
1
+ {
2
+ "access_token": "1.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-2346678-124328",
3
+ "expires_in": 86400,
4
+ "refresh_token": "2.385d55f8615fdfd9edb7c4b5ebdc3e39.604800.1293440400-2346678-124328",
5
+ "scope": "public",
6
+ "session_key": "ANXxSNjwQDugf8615OnqeikRMu2bKaXCdlLxn",
7
+ "session_secret": "248APxvxjCZ0VEC43EYrvxqaK4oZExMB"
8
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "client_id": "ZLycGmiUcCkrSb3t7zSD8uV6",
3
+ "userid": 689911016,
4
+ "scope": "basic super_msg",
5
+ "create_time": 1364555477,
6
+ "expire_in": 2591980
7
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baidu-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lonre Wang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-27 00:00:00.000000000 Z
11
+ date: 2013-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multipart-post
@@ -61,9 +61,11 @@ files:
61
61
  - lib/baidu/errors/error.rb
62
62
  - lib/baidu/oauth.rb
63
63
  - lib/baidu/oauth/client.rb
64
+ - lib/baidu/oauth/flow/authorization_code.rb
64
65
  - lib/baidu/oauth/flow/base.rb
65
- - lib/baidu/oauth/flow/code.rb
66
+ - lib/baidu/oauth/flow/client_credentials.rb
66
67
  - lib/baidu/oauth/flow/device.rb
68
+ - lib/baidu/oauth/flow/implicit_grant.rb
67
69
  - lib/baidu/pcs.rb
68
70
  - lib/baidu/pcs/client.rb
69
71
  - lib/baidu/session.rb
@@ -83,6 +85,7 @@ files:
83
85
  - spec/fixtures/delete.json
84
86
  - spec/fixtures/diff.json
85
87
  - spec/fixtures/empty.json
88
+ - spec/fixtures/get_token_client_credentials.json
86
89
  - spec/fixtures/get_token_code.json
87
90
  - spec/fixtures/get_token_device.json
88
91
  - spec/fixtures/list.json
@@ -102,6 +105,7 @@ files:
102
105
  - spec/fixtures/search.json
103
106
  - spec/fixtures/stream_list.json
104
107
  - spec/fixtures/streaming.m3u8
108
+ - spec/fixtures/token_info.json
105
109
  - spec/fixtures/upload.json
106
110
  - spec/fixtures/upload_block.json
107
111
  - spec/fixtures/user_and_device_code.json
@@ -143,6 +147,7 @@ test_files:
143
147
  - spec/fixtures/delete.json
144
148
  - spec/fixtures/diff.json
145
149
  - spec/fixtures/empty.json
150
+ - spec/fixtures/get_token_client_credentials.json
146
151
  - spec/fixtures/get_token_code.json
147
152
  - spec/fixtures/get_token_device.json
148
153
  - spec/fixtures/list.json
@@ -162,6 +167,7 @@ test_files:
162
167
  - spec/fixtures/search.json
163
168
  - spec/fixtures/stream_list.json
164
169
  - spec/fixtures/streaming.m3u8
170
+ - spec/fixtures/token_info.json
165
171
  - spec/fixtures/upload.json
166
172
  - spec/fixtures/upload_block.json
167
173
  - spec/fixtures/user_and_device_code.json