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 +4 -4
- data/HISTORY.md +5 -0
- data/README.md +73 -20
- data/lib/baidu/oauth.rb +1 -0
- data/lib/baidu/oauth/client.rb +50 -7
- data/lib/baidu/oauth/flow/{code.rb → authorization_code.rb} +9 -12
- data/lib/baidu/oauth/flow/base.rb +18 -9
- data/lib/baidu/oauth/flow/client_credentials.rb +37 -0
- data/lib/baidu/oauth/flow/device.rb +6 -13
- data/lib/baidu/oauth/flow/implicit_grant.rb +57 -0
- data/lib/baidu/version.rb +1 -1
- data/spec/baidu/oauth/client_spec.rb +72 -19
- data/spec/fixtures/get_token_client_credentials.json +8 -0
- data/spec/fixtures/token_info.json +7 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7d739a156a7feec33727249033320452ff730d1
|
4
|
+
data.tar.gz: 1db71954fe27d31241176786cab6ec5dbd18ae09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ea790ba81dabc1968e53664a95e30b741ba1d9c282d4631edeac230b9b2c9e631d359add53badf7636e7acda6dfff7f924ccf98ceeced42b166627766d9afe7
|
7
|
+
data.tar.gz: 19e130371ed9e9d9f804b0fbf60e1e6a6e4dc5c9df7f1b50e715cd3152b404c942a1594202194a8dd1e1b775c16bf6e74d126cb55b40bbbfeeaf8e690eab4780
|
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Baidu SDK for Ruby [](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
|
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
|
-
|
71
|
+
|
72
|
+
3. Baidu OAuth 有四种获取 Access Token 的方式,包括 `Authorization Code`, `Implicit Grant`, `Client Credentials`, `Device`以及一个刷新方式`Refresh Token`
|
59
73
|
|
60
74
|
```ruby
|
61
|
-
|
62
|
-
client.
|
63
|
-
|
64
|
-
|
65
|
-
client.
|
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
|
-
|
100
|
+
|
101
|
+
4. `Baidu::Session` 授权信息
|
102
|
+
|
103
|
+
所有 `get_token` 及 `refresh` 均返回 `Baidu::Session`,包含授权信息,如:
|
68
104
|
|
69
105
|
```ruby
|
70
|
-
session = client.
|
71
|
-
session
|
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.
|
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.
|
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
|
-
|
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
|
-
|
147
|
-
|
148
|
-
|
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
data/lib/baidu/oauth/client.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require 'baidu/oauth/flow/
|
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
|
32
|
+
# @!method authorization_code_flow
|
31
33
|
# 采用 Authorization Code 获取 Access Token 的授权验证流程
|
32
|
-
# @return [Flow::
|
34
|
+
# @return [Flow::AuthorizationCode]
|
35
|
+
#
|
33
36
|
# @!method device_flow
|
34
37
|
# 采用 Device Code 获取 Access Token 的授权验证流程
|
35
38
|
# @return [Flow::Device]
|
36
|
-
#
|
37
|
-
#
|
38
|
-
|
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
|
-
|
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
|
14
|
-
include
|
13
|
+
class AuthorizationCode < Base
|
14
|
+
include Authable
|
15
|
+
include Tokenable
|
15
16
|
|
16
|
-
#
|
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 附带的
|
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
|
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
|
-
|
7
|
-
|
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 =
|
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
|
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(
|
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
|
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
@@ -44,25 +44,38 @@ describe Baidu::OAuth::Client do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
context '#authorize_url' do
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
63
|
-
|
64
|
-
@client.
|
65
|
-
|
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.
|
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.
|
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
|
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
|
+
}
|
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.
|
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
|
+
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/
|
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
|