baidu-sdk 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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