Javascript 如何通过jQueryAjax从使用OAuth1.0身份验证的UpworkAPI请求JSONP文件?
我需要通过jQueryAjax从服务器请求一个JSONP文件。UpWorkAPI使用OAuth 1.0身份验证 我不熟悉Oauth,但在过去几天里一直在阅读有关它的内容,我大致了解它是如何工作的,但在这个特定场景/环境中实现它非常困难。几天来我一直在绞尽脑汁,Upwork API支持也没有多大帮助:( 我需要通过OAuth 1.0中所有必要的步骤,并获得与请求url一起传递的OAuth参数。请帮助! 以下是我迄今为止所做的工作:Javascript 如何通过jQueryAjax从使用OAuth1.0身份验证的UpworkAPI请求JSONP文件?,javascript,jquery,ajax,api,oauth,Javascript,Jquery,Ajax,Api,Oauth,我需要通过jQueryAjax从服务器请求一个JSONP文件。UpWorkAPI使用OAuth 1.0身份验证 我不熟悉Oauth,但在过去几天里一直在阅读有关它的内容,我大致了解它是如何工作的,但在这个特定场景/环境中实现它非常困难。几天来我一直在绞尽脑汁,Upwork API支持也没有多大帮助:( 我需要通过OAuth 1.0中所有必要的步骤,并获得与请求url一起传递的OAuth参数。请帮助! 以下是我迄今为止所做的工作: // My Upwork API key and secret v
// 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");
},
});
代码笔:
提前感谢!TLDR我从OAuth 1.0过程描述开始,以确保下面的代码示例和我的结论都是清晰的。 如果OAuth进程已清除,请跳到代码部分 OAuth1.0进程 我使用以下术语(它们不同于官方术语,但希望能让事情更清楚):
- 应用程序-您的应用程序
- 服务-从中请求数据的服务
- 用户-允许您访问服务存储的数据的用户
客户端密钥
,以便服务知道是谁询问
该请求是使用客户端密码签署的,该服务也拥有该密码,并且可以验证它是否确实是来自您的应用程序的请求,而不是来自窃取您的客户端密钥的其他人的请求(这就是您不应该向任何人显示您的密码的原因)
服务器返回临时oauth令牌
+临时oauth密钥
在Upwork的情况下,您将此请求发送给
步骤2.要求用户授予您访问权限。
您的应用程序只是将用户重定向到服务提供的特殊URL
该服务显示一个对话框,用户可以在其中为您的应用程序提供访问权限。
此特殊URL包含步骤1中的临时令牌
,因此服务知道哪个应用程序请求访问
如果您有一个web应用程序,只需在浏览器中打开此特殊url即可。
然后,该服务使用oauth_回调
(将用户重定向回的URL)重定向回您的应用程序。
该服务还将oauth\u验证器
传递给oauth\u回调
URL
如果您有一个桌面应用程序,它应该启动浏览器,该服务可以将oauth\u校验器
显示为字符串,这样用户可以手动复制它并粘贴回您的应用程序。在这种情况下,您可以将oauth\u calback
设置为特殊的oob
(带外)值。
规范中没有严格描述此部分(没有重定向回),因此详细信息取决于服务。
它可能根本不受支持,或者以其他方式得到支持
对于Upwork,您将用户发送到URL{temporary token}
步骤3.获取真正的oauth访问令牌。
您的应用程序将临时令牌从步骤1和oauth验证器从步骤2发送到服务。
请求再次被签名,但这次使用的是客户端密码
和临时令牌密码
。
服务使用访问令牌+机密进行响应
在Upwork的情况下,URL是
这是获得真正的access toking并开始使用服务API的3个步骤。
规范中的示例也很好且清晰
还要注意,OAuth 1.0不能在100%客户端应用程序中安全使用。
在步骤1中,您需要使用私有的客户机机密
,任何人都不应该知道它(因此您不能将其放入客户端代码中)。
在步骤2中,服务将把浏览器重定向回oauth\u回调
,而您无法在客户端处理它
从技术上讲,如果您在没有回调的情况下使用场景(如桌面应用程序),则可以使用oauth客户端。在这种情况下,用户需要手动将验证器复制回您的应用程序。
这个场景也应该得到Servcie的支持(Upwork不支持它,请参见下文)
步骤4.使用服务API
现在,一旦您获得了访问令牌,就可以发出API请求来获取数据,在这里您可以发送步骤3中的客户机密钥和访问令牌。
请求使用客户机密码
+访问令牌密码
签名
该过程中最复杂的部分是请求签名,规范中详细介绍了这一部分,但最好使用库
允许您在node.js和客户端javascript中对请求进行签名。
您仍然需要从应用程序中执行oauth步骤,该库只会帮助您进行签名
代码
我从浏览器javascript测试了步骤1
,Upwork不支持这种情况。
如果我使用ajax发送常规POST请求,它将返回“Access Control Allow Origin错误。如果我使用
JSONP`尝试此请求,Upwork将以404错误响应
因此,JSONP
不支持api/auth/v1/oauth/token/request
端点
步骤1-3应该使用服务器端完成(无论如何,客户端身份验证是不安全的)
以下是令牌请求的外观(步骤1
):
完整的代码是
请注意,Upwork具有相同的功能,但我并没有使用它来手动完成所有事情。
请求使用签名
步骤2
在浏览器中执行,在这里,您只需像“”一样打开url并获取oauth验证器。
在现实生活中
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);
});
};
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);
});
};
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);
});
};
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);
},
});
};
$ 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
>
> 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
> 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}