简体   繁体   English

如何通过使用OAuth 1.0身份验证的Upwork API通过jQuery AJAX请求JSONP文件?

[英]How to request a JSONP file via jQuery AJAX from the Upwork API that uses OAuth 1.0 authentication?

I need to request a JSONP file from the Upwork API via jQuery AJAX. 我需要通过jQuery AJAX从Upwork API请求一个JSONP文件。 The Upwork API uses OAuth 1.0 authentication. Upwork API使用OAuth 1.0身份验证。

I'm new to Oauth but been reading about it in the last few days and I generally understand how it works but it's been very hard to implement it in this specific scenario/environment. 我是Oauth的新手,但在过去的几天里一直在阅读它,我一般都了解它是如何工作的,但在这个特定的场景/环境中实现它非常困难。 Been banging my head for days and the Upwork API support have not been much help :( 几天来一直在敲我的头,Upwork API支持没有太大帮助:(

I need to pass thru all the necessary steps in OAuth 1.0 and get the OAuth parameters passed with the request url. 我需要通过OAuth 1.0中的所有必要步骤,并获取与请求网址一起传递的OAuth参数。 Please help! 请帮忙!

Here's what I've done so far: 这是我到目前为止所做的:

// 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");
  },
});

CodePen: http://codepen.io/nunoarruda/pen/xZBEzB?editors=1010 CodePen: http ://codepen.io/nunoarruda/pen/xZBEzB?editors = 1010

Thanks in advance! 提前致谢!

TLDR I am starting with the OAuth 1.0 process description to be sure that the code examples below and my conclusions will be clear. TLDR我从OAuth 1.0流程描述开始,以确保下面的代码示例和我的结论将是清楚的。 Skip to the The code part if OAuth process is clear. 如果OAuth流程已清除,请跳至The code部分。

The OAuth 1.0 process OAuth 1.0流程

I use the following terms below (they differ from the official terminology, but hopefully will make things clearer): 我使用下面的术语(它们与官方术语不同,但希望能使事情更清楚):

  • App - your application 应用 - 您的应用
  • Service - the service you request data from 服务 - 您从中请求数据的服务
  • User - the user who gives you access his data stored by the Service 用户 - 允许您访问服务存储的数据的用户

Preparation. 制备。 Register your App in the Service 在服务中注册您的应用程序

You will get the client key and secret used to start the Oauth process. 您将获得用于启动Oauth进程的客户端密钥和密钥。

In the case of Upwork, you do this here - https://www.upwork.com/services/api/apply . 对于Upwork,您可以在此处执行此操作 - https://www.upwork.com/services/api/apply

Step 1. Get the temporary oauth token. 步骤1.获取临时oauth令牌。

This request is made by your App to the Service. 此请求由您的应用程序提供给服务。 Your App passes the client key , so the Service knows who asks. 您的应用程序传递client key ,因此服务知道谁问。

The request is signed using the client secret , the Service also has it and can verify if it is actually the request from your App and not from someone else who stole your client key (this is the reason why you shouldn't show your secret to anyone). 请求是使用client secret签署的,服务也有它,并且可以验证它是否实际上是来自您的应用程序的请求,而不是来自窃取您的客户端密钥的其他人(这就是为什么您不应该向您显示您的秘密的原因)任何人)。

Server returns the temporary oauth token + temporary oauth secret . 服务器返回temporary oauth token + temporary oauth secret

In the case of Upwork you send this request to the https://www.upwork.com/api/auth/v1/oauth/token/request 在Upwork的情况下,您将此请求发送到https://www.upwork.com/api/auth/v1/oauth/token/request

Step 2. Ask the user to grant you an access. 步骤2.要求用户授予您访问权限。

Your application just redirects the user to the special URL provided by Service. 您的应用程序只是将用户重定向到Service提供的特殊URL。

The service shows a dialog where the user can provide access for your application. 该服务显示一个对话框,用户可以为您的应用程序提供访问权限。 This special URL includes the temporary token from the step 1, so the Service knows which application asks for the access. 此特殊URL包括步骤1中的temporary token ,因此服务知道哪个应用程序要求访问。

If you have a web-application, you just open this special url in the browser. 如果您有一个Web应用程序,只需在浏览器中打开此特殊URL即可。 The Service then redirects back to your App, using the oauth_callback (the URL to redirect the user back to). 然后,服务使用oauth_callback (用于将用户重定向回的URL)重定向回应用程序。 The Service also passes the oauth_verifier to the oauth_callback URL. 该服务还将oauth_verifier传递给oauth_callback URL。

If you have a desktop application, it should launch the browser and the Service can show the oauth_verifier as a string, so the user can manually copy it and paste back to your App. 如果您有桌面应用程序,它应该启动浏览器,并且服务可以将oauth_verifier显示为字符串,因此用户可以手动复制它并粘贴回您的应用程序。 In this case you set the oauth_calback to the special oob (out-of-band) value. 在这种情况下,您将oauth_calback设置为特殊的oob (带外)值。 This part (without the redirect back) is not strictly described in the specification, so the details depend on the Service. 此部分(没有重定向返回)未在规范中严格描述,因此详细信息取决于服务。 It may be not supported at all or supported in some other way. 它可能根本不受支持或以其他方式支持。

In the case of Upwork you send the user to the URL https://www.upwork.com/services/api/auth?oauth_token= {temporary token} 在Upwork的情况下,您将用户发送到URL https://www.upwork.com/services/api/auth?oauth_token= {temporary token}

Step 3. Get the real oauth access token. 第3步。获取真正的oauth访问令牌。

Your app sends the temporary token from the step 1 and oauth verifier from the step 2 to the Service. 您的应用程序将步骤1中的临时令牌和步骤2中的oauth验证程序发送到服务。 The request is again signed, but this time using the client secret and temporary token secret . 请求再次签名,但这次使用client secrettemporary token secret Service responds with the access token + secret. 服务使用访问令牌+机密进行响应。

In the case of Upwork the URL is https://www.upwork.com/api/auth/v1/oauth/token/access 在Upwork的情况下,URL是https://www.upwork.com/api/auth/v1/oauth/token/access

These are 3 steps to get the real access toking and start using the Service API. 这些是获得真实访问权限并开始使用Service API的3个步骤。 The example in the specification is also good and clear, check it . 规范中的示例也很好且清晰, 请检查它

Also note that the OAuth 1.0 can not be safely used in 100% client-side apps. 另请注意,OAuth 1.0无法安全地用于100%客户端应用程序。 On the step 1 you need to use the private client secret which should not be known to anyone (so you must not place it into your client-side code). 在步骤1中,您需要使用任何人都不应知道的私有client secret (因此您不能将其放入客户端代码中)。 On the step 2 the Service will redirect the browser back to the oauth_callback and you can't handle it client-side. 在第2步,服务将浏览器重定向回oauth_callback ,您无法在客户端处理它。

Technically it is possible to use oauth client-side if you use the scenario without the callback like for the desktop application. 从技术上讲,如果您使用没有回调的方案(如桌面应用程序),则可以使用oauth客户端。 In this case user will need to manually copy the verifier back to your application. 在这种情况下,用户需要手动将验证程序复制回应用程序。 This scenario should also be supported by the Servcie (Upwork doesn't support it, see below). Servcie也应该支持这种情况(Upwork不支持它,见下文)。

Step 4. Use the Service API 步骤4.使用Service API

Now, once you get the access token, you can make API requests to get the data, here you send both your client key and the access token from the Step 3. Requests are signed with client secret + access token secret . 现在,一旦获得访问令牌,您就可以发出API请求来获取数据,在此您从步骤3发送client keyaccess token 。请求使用client secret + access token secret进行签名。

The most complex part of the process is requests signing, it is covered in details in the specification, but this is where it is better to use a library. 该过程中最复杂的部分是请求签名,规范中详细介绍了这一点,但最好是使用库。

The oauth-1.0a allows you to sign your requests in node.js and in client-side javascript. oauth-1.0a允许您在node.js和客户端javascript中签署您的请求。 You still need to perform the oauth steps from your application, the library will only help you with signing. 您仍然需要从应用程序执行oauth步骤,库只会帮助您进行签名。

The code 代码

I tested the Step 1 from the browser javascript and Upwork doesn't support this scenario. 我在浏览器javascript中测试了Step 1 ,Upwork不支持这种情况。 If I send the regular POST request with ajax, it returns the 'Access-Control-Allow-Origin error. And if I try this request using 如果我使用ajax发送常规POST请求,它将返回'Access-Control-Allow-Origin error. And if I try this request using error. And if I try this request using JSONP`, Upwork responds with the 404 error. error. And if I try this request using JSONP` error. And if I try this request using ,Upwork会响应404错误。

So there is no JSONP support for the api/auth/v1/oauth/token/request endpoint. 因此,对api/auth/v1/oauth/token/request端点没有JSONP支持。

The Steps 1-3 should be done using the server-side (anyway client side authentication would be non-secure). 步骤1-3应该使用服务器端完成(无论如何客户端身份验证将是不安全的)。

Here is how the token request looks ( Step 1 ): 以下是令牌请求的外观( 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);
    });
};

The full code is here . 完整的代码在这里

Note that Upwork has the nodejs library , but I didn't use it just to do all things manually. 请注意,Upwork有nodejs库 ,但我没有使用它只是手动完成所有事情。 Requests are signed using oauth-1.0a . 使用oauth-1.0a签署请求。

The Step 2 is performed in the browser, here you just open the url like ' https://www.upwork.com/services/api/auth?oauth_token=xxx ' and get the oauth verifier. Step 2在浏览器中执行,在这里您只需打开“ https://www.upwork.com/services/api/auth?oauth_token=xxx ”等网址即可获取oauth验证程序。 In the real-life scenario, your application will specify the oauth_callback parameter and Upwork will send the oauth verifier to your application. 在现实生活中,您的应用程序将指定oauth_callback参数,Upwork会将oauth验证程序发送到您的应用程序。 In this example I just manually copy it from the browser and pass to the next step. 在这个例子中,我只是从浏览器手动复制它并转到下一步。

Having the oauth verifier, you can get the permanent access token ( Step 3 ): 使用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);
    });
};

Finally, you can use the API, Step 4 (again, this is server-side code): 最后,您可以使用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);
    });
};

It is possible to do use the API from the client side (although it is not good, because you need to put your access token and secret into the code). 可以从客户端使用API​​(尽管它不好,因为您需要将访问令牌和秘密放入代码中)。

The solution is tricky, because the documentation( https://developers.upwork.com/?lang=node#getting-started_cross-domain-requests ) is not complete and not exactly correct. 解决方案很棘手,因为文档( https://developers.upwork.com/?lang=node#getting-started_cross-domain-requests )不完整且不完全正确。

It says to add callback=? 它说添加callback=? to the request, but jQuery adds this parameter automatically when you set JSONP data type. 对于请求,但是当您设置JSONP数据类型时,jQuery会自动添加此参数。 Also the parameter value is set to some random string, so I thought that this parameter should not be signed, but it appears that it should: 参数值也设置为一些随机字符串,所以我认为这个参数不应该被签名,但看起来它应该:

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);
      },
    });
};

Anyway this is insecure, and since you need the server side for Oauth, you also can use it to make the API requests to API and return results to the client side. 无论如何这是不安全的,因为您需要Oauth的服务器端,您也可以使用它来向API发出API请求并将结果返回给客户端。

How to use the code example 如何使用代码示例

Get the copy of the nodejs-upwork-oauth folder, do npm install and start the node.js console: 获取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
>

Now open the test.html in the browser and open the JS console, run: 现在在浏览器中打开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

Go back to the nodejs console: 返回nodejs控制台:

> oauthTest.step3_accessToken('oauth verifier here')
> // wait for the result
{ public: 'nnnnn',
  secret: 'kkkkk' }
> oauthTest.queryAPI()
> // see the query result

And go back to the browser: 然后回到浏览器:

> queryAPI('access token public', 'access token secret')
< Object {server_time: 1456301893, auth_user: Object, profile_access: "public,odesk", jobs: Array[10], paging: Object}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM