如何通过 jQuery AJAX 从使用 OAuth 1.0 身份验证的 Upwork API 请求 JSONP 文件?
Posted
技术标签:
【中文标题】如何通过 jQuery AJAX 从使用 OAuth 1.0 身份验证的 Upwork API 请求 JSONP 文件?【英文标题】:How to request a JSONP file via jQuery AJAX from the Upwork API that uses OAuth 1.0 authentication? 【发布时间】:2016-05-26 07:01:45 【问题描述】:我需要通过 jQuery AJAX 从Upwork API 请求一个 JSONP 文件。 Upwork API 使用 OAuth 1.0 身份验证。
我是 Oauth 的新手,但最近几天一直在阅读它,我大致了解它的工作原理,但在这个特定的场景/环境中实施它非常困难。几天来一直在敲我的脑袋,Upwork API 支持并没有太大帮助:(
我需要通过 OAuth 1.0 中的所有必要步骤并获取随请求 url 传递的 OAuth 参数。请帮忙!
这是我到目前为止所做的:
// My Upwork API key and secret
var api_key = 'xxx',
api_secret = 'xxx';
// TO-DO
// OAuth 1.0 authentication
// TO-DO
// required oauth parameters
// https://developers.upwork.com/?lang=node#authentication_required-oauth-10-parameters
var oauth_consumer_key = '',
oauth_signature = '',
oauth_nonce = '',
oauth_signature_method = '',
oauth_timestamp = '',
oauth_token = '';
// Compose request url with required oauth parameters
var url = "https://www.upwork.com/api/profiles/v2/search/jobs.json?q=java&callback=?";
url += "&oauth_consumer_key="+oauth_consumer_key;
url += "&oauth_signature="+oauth_signature;
url += "&oauth_nonce="+oauth_nonce;
url += "&oauth_signature_method="+oauth_signature_method;
url += "&oauth_timestamp="+oauth_timestamp;
url += "&oauth_token="+oauth_token;
// Ajax request
// https://developers.upwork.com/?lang=node#getting-started_cross-domain-requests
$.ajax(
url: url,
dataType: 'JSONP',
success:function(json)
alert("Success: "+json.server_time);
,
error:function()
alert("Error");
,
);
代码笔:http://codepen.io/nunoarruda/pen/xZBEzB?editors=1010
提前致谢!
【问题讨论】:
你能分享你的服务器详细信息(URL)吗? 为什么不使用像github.com/ddo/oauth-1.0a这样的库 @saravanakumar 如果您要求从 API 获取 URL 以执行 Oauth 过程的所有请求,您可以在文档 developers.upwork.com/?lang=node#authentication_oauth-10 中找到它们 @Benvorth 我已经尝试了几次,但无法成功。此外,看起来该框架仅处理 Oauth 过程的一部分,即您已经拥有令牌密钥和令牌秘密的部分。 OAuth 不仅仅是传递用户名/密码之类的身份验证参数 - 还有更多功能,这就是为什么建议您使用其他可以为您完成必要工作的谎言(请参阅 oauthbible.com for有关身份验证过程如何工作的更多信息) 【参考方案1】:TLDR 我从 OAuth 1.0 流程描述开始,以确保下面的代码示例和我的结论清楚。
如果 OAuth 过程清楚,请跳到 The code
部分。
OAuth 1.0 流程
我使用以下术语(它们与官方术语不同,但希望能让事情更清楚):
应用 - 您的应用 服务 - 您请求数据的服务 用户 - 允许您访问其服务存储的数据的用户准备。在服务中注册您的应用程序
您将获得用于启动 Oauth 过程的客户端密钥和秘密。
对于 Upwork,您可以在此处执行此操作 - https://www.upwork.com/services/api/apply。
第 1 步。获取临时 oauth 令牌。
此请求由您的应用向服务发出。
您的应用通过了client key
,因此服务知道谁在询问。
请求是使用client secret
签名的,服务也有它,并且可以验证它是否真的是来自您的应用程序的请求,而不是来自窃取您客户端密钥的其他人(这就是为什么您不应该向任何人展示你的秘密)。
服务器返回temporary oauth token
+ temporary oauth secret
。
如果是 Upwork,请将此请求发送至 https://www.upwork.com/api/auth/v1/oauth/token/request
第 2 步。请求用户授予您访问权限。
您的应用程序只是将用户重定向到 Service 提供的特殊 URL。
该服务显示一个对话框,用户可以在其中为您的应用程序提供访问权限。
这个特殊的 URL 包括步骤 1 中的temporary token
,因此服务知道哪个应用程序请求访问。
如果您有一个网络应用程序,您只需在浏览器中打开这个特殊的 url。
然后,该服务使用 oauth_callback
(将用户重定向回的 URL)重定向回您的应用程序。
该服务还将oauth_verifier
传递给oauth_callback
URL。
如果您有桌面应用程序,它应该启动浏览器并且服务可以将oauth_verifier
显示为字符串,因此用户可以手动将其复制并粘贴回您的应用程序。在这种情况下,您将oauth_calback
设置为特殊的oob
(带外)值。
这部分(没有重定向返回)在规范中没有严格描述,所以细节取决于服务。
它可能根本不受支持或以其他方式支持。
在 Upwork 的情况下,您将用户发送到 URL https://www.upwork.com/services/api/auth?oauth_token=temporary token
第 3 步。获取真正的 oauth 访问令牌。
您的应用将第 1 步中的临时令牌和第 2 步中的 oauth 验证器发送到服务。
请求再次被签名,但这次使用client secret
和temporary token secret
。
服务以访问令牌 + 秘密进行响应。
对于 Upwork,URL 是 https://www.upwork.com/api/auth/v1/oauth/token/access
这些是获取真正访问权限并开始使用服务 API 的 3 个步骤。 规范中的例子也很好很清晰,check it。
另请注意,OAuth 1.0 不能在 100% 客户端应用程序中安全使用。
在第 1 步中,您需要使用任何人都不应该知道的私有 client secret
(因此您不得将其放入您的客户端代码中)。
在第 2 步中,服务会将浏览器重定向回oauth_callback
,您无法在客户端处理它。
从技术上讲,如果您使用没有回调的场景(如桌面应用程序),则可以使用 oauth 客户端。在这种情况下,用户需要手动将验证器复制回您的应用程序。 Servcie 也应该支持这种场景(Upwork 不支持,见下文)。
第 4 步。使用服务 API
现在,一旦您获得访问令牌,您就可以发出 API 请求来获取数据,在这里您可以发送第 3 步中的 client key
和 access token
。
请求使用client secret
+ access token secret
签名。
流程中最复杂的部分是请求签名,规范中有详细介绍,但这是最好使用库的地方。
oauth-1.0a 允许您在 node.js 和客户端 javascript 中签署您的请求。 您仍然需要从您的应用程序中执行 oauth 步骤,该库只会帮助您进行签名。
代码
我从浏览器 javascript 中测试了 Step 1
,但 Upwork 不支持这种情况。
如果我使用 ajax 发送常规 POST 请求,它会返回“Access-Control-Allow-Originerror. And if I try this request using
JSONP”,Upwork 会以 404 错误响应。
所以JSONP
不支持api/auth/v1/oauth/token/request
端点。
步骤 1-3 应使用服务器端完成(无论如何客户端身份验证都是不安全的)。
这是令牌请求的外观 (Step 1
):
oauthTest.step1_tempToken = function()
var request_data =
url: 'https://www.upwork.com/api/auth/v1/oauth/token/request',
method: 'POST',
data:
;
request(
url: request_data.url,
method: request_data.method,
form: oauthTest.oauth.authorize(request_data) // no token yet
, function(error, response, body)
var data = qs.parse(body);
console.log(data);
);
;
完整代码为here。
请注意,Upwork 有 nodejs library,但我并没有使用它来手动完成所有操作。 请求使用oauth-1.0a签名。
Step 2
是在浏览器中执行的,在这里您只需打开 'https://www.upwork.com/services/api/auth?oauth_token=xxx' 之类的 url 并获取 oauth 验证器。
在实际场景中,您的应用程序将指定oauth_callback
参数,Upwork 将向您的应用程序发送 oauth 验证器。
在此示例中,我只是从浏览器手动复制它并传递到下一步。
拥有 oauth 验证器,您可以获得永久访问令牌 (Step 3
):
oauthTest.step3_accessToken = function(oauth_verifier)
var request_data =
url: 'https://www.upwork.com/api/auth/v1/oauth/token/access',
method: 'POST',
data:
oauth_verifier: oauth_verifier
;
request(
url: request_data.url,
method: request_data.method,
form: oauthTest.oauth.authorize(request_data, oauthTest.tempToken) // use the temp token
, function(error, response, body)
var data = qs.parse(body);
console.log(data);
);
;
最后,您可以使用 API,Step 4
(同样,这是服务器端代码):
oauthTest.queryAPI = function()
var request_data =
url: 'https://www.upwork.com/api/profiles/v2/search/jobs.json',
method: 'GET',
data:
'q': 'java'
;
request(
url: request_data.url,
method: request_data.method,
qs: oauthTest.oauth.authorize(request_data, oauthTest.accessToken) // use the access token
, function(error, response, body)
console.log(body);
);
;
可以从客户端使用 API(虽然不好,因为您需要将访问令牌和密码放入代码中)。
解决方案很棘手,因为文档 (https://developers.upwork.com/?lang=node#getting-started_cross-domain-requests) 不完整且不完全正确。
它说要在请求中添加callback=?
,但是当你设置JSONP
数据类型时,jQuery会自动添加这个参数。参数值也设置为一些随机字符串,所以我认为这个参数不应该被签名,但它似乎应该:
function queryAPI(public, secret)
var accessToken =
public: public,
secret: secret
var request_data =
url: 'https://www.upwork.com/api/profiles/v2/search/jobs.json',
method: 'GET',
data:
'q': 'java',
'callback': 'jsoncallback'
;
// It looks like a bug on the Upwork side, the `callback` parameter is usually
// selected randomly by jQuery, so server side should skip it from the signature
// validation, but it doesn't, so we sign the request with `callback` parameter
// and then remove it from data, because it this parameter is automatically added
// by jQuery, we also set the static value for callback - 'jsoncallback`
var data = oauth.authorize(request_data, accessToken);
delete data.callback;
// Ajax request
// https://developers.upwork.com/?lang=node#getting-started_cross-domain-requests
$.ajax(
// url: url,
url: request_data.url,
dataType: 'JSONP',
jsonpCallback: 'jsoncallback',
// here the data will contain 'q=java' as well as all the oauth parameters
// the request type will be GET (since this is JSONP), so all parameters will
// be converted to the query string
// you can check the URL in the developer console, in the list of network requests
//data: oauth.authorize(request_data, accessToken),
data: data,
cache: true, // this removes the '_' parameter
success:function(json)
console.log(json);
,
error: function(error)
console.log(error);
,
);
;
无论如何这是不安全的,并且由于您需要服务器端进行 Oauth,您也可以使用它向 API 发出 API 请求并将结果返回给客户端。
如何使用代码示例
获取 nodejs-upwork-oauth 文件夹的副本,执行npm install
并启动 node.js 控制台:
$ node
> oauthTest = require('./server')
> oauthTest.step1_tempToken()
> // wait for the result
public: 'xxxx',
secret: 'yyyy'
> // copy the public temp access token
> // don't exit it yet
>
现在在浏览器中打开test.html
并打开JS控制台,运行:
> step2_askUser('temp_access_token_here')
> // it will open the upwork auth page in new tab
Application authorized
jobs-alert has been authorized.
Your oauth_verifier=zzzz
You can close this window and return to your application.
> // authorize there and copy the oauth_verifier
回到nodejs控制台:
> oauthTest.step3_accessToken('oauth verifier here')
> // wait for the result
public: 'nnnnn',
secret: 'kkkkk'
> oauthTest.queryAPI()
> // see the query result
然后返回浏览器:
> queryAPI('access token public', 'access token secret')
< Object server_time: 1456301893, auth_user: Object, profile_access: "public,odesk", jobs: Array[10], paging: Object
【讨论】:
使用有效的客户端请求更新了答案。以上是关于如何通过 jQuery AJAX 从使用 OAuth 1.0 身份验证的 Upwork API 请求 JSONP 文件?的主要内容,如果未能解决你的问题,请参考以下文章
PHP-AJAX:如何通过 php/json 数组从查询中填充 jquery 数据表
如何实现一个 jquery ajax 表单,它通过 php 请求从 web api 请求信息?
如何使用多个 Django FBV 通过 Ajax+jQuery 捕获和保存数据
如何通过 jQuery AJAX 从使用 OAuth 1.0 身份验证的 Upwork API 请求 JSONP 文件?