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

时间:2022-08-22 11:07:13

I need to request a JSONP file from the Upwork API via jQuery AJAX. The Upwork API uses OAuth 1.0 authentication.

我需要通过jQuery AJAX从Upwork API请求一个JSONP文件。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. Been banging my head for days and the Upwork API support have not been much help :(

我是Oauth的新手,但是最近几天我一直在阅读关于Oauth的文章,我大致了解它是如何工作的,但是在这个特定的场景/环境中很难实现它。几天来,我的头一直在不停地敲打着,而改进的API支持并没有起到多大的帮助:

I need to pass thru all the necessary steps in OAuth 1.0 and get the OAuth parameters passed with the request url. Please help!

我需要通过OAuth 1.0中的所有必要步骤来传递,并获得通过请求url传递的OAuth参数。请帮助!

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!

提前谢谢!

1 个解决方案

#1


4  

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. Skip to the The code part if OAuth process is clear.

TLDR我将从OAuth 1.0过程描述开始,以确保下面的代码示例和我的结论是清晰的。如果OAuth过程是清晰的,跳过代码部分。

The OAuth 1.0 process

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.

This request is made by your App to the Service. Your App passes the client key, so the Service knows who asks.

这个请求是由您的应用程序提供给服务的。你的应用程序通过客户端密钥,这样服务就知道谁在问。

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).

该请求使用客户端秘密进行签名,该服务也有这个秘密,并可以验证它是否是来自您的应用程序的请求,而不是窃取您的客户端密钥的其他人的请求(这就是为什么您不应该向任何人透露您的秘密)。

Server returns the temporary oauth token + temporary oauth secret.

服务器返回临时oauth令牌+临时oauth秘密。

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.

Your application just redirects the user to the special URL provided by 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中的临时标记,因此服务知道哪个应用程序请求访问。

If you have a web-application, you just open this special url in the browser. The Service then redirects back to your App, using the oauth_callback (the URL to redirect the user back to). The Service also passes the oauth_verifier to the oauth_callback URL.

如果您有一个web应用程序,您只需在浏览器中打开这个特殊的url。然后,该服务使用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. In this case you set the oauth_calback to the special oob (out-of-band) value. 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.

如果您有一个桌面应用程序,它应该启动浏览器,服务可以将oauth_verifier显示为字符串,这样用户就可以手动复制并粘贴回应用程序。此部分(没有重定向返回)在规范中没有严格描述,因此细节取决于服务。它可能完全不被支持或以其他方式被支持。

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 = {临时令牌}

Step 3. Get the real oauth access token.

Your app sends the temporary token from the step 1 and oauth verifier from the step 2 to the Service. The request is again signed, but this time using the client secret and temporary token secret. Service responds with the access token + secret.

您的应用程序将第1步和oauth验证器的临时标记从步骤2发送到服务。再次对请求进行签名,但这一次使用客户端秘密和临时令牌秘密。服务响应访问令牌+秘密。

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. The example in the specification is also good and clear, check it.

这是获取真正访问并开始使用服务API的三个步骤。规范中的示例也很好很清楚,请检查。

Also note that the OAuth 1.0 can not be safely used in 100% client-side apps. 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). On the step 2 the Service will redirect the browser back to the oauth_callback and you can't handle it client-side.

还要注意,OAuth 1.0不能安全地用于100%的客户端应用程序。在步骤1中,您需要使用不应该被任何人知道的私有客户端秘密(因此您不能将其放入客户端代码中)。在步骤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. 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).

从技术上讲,如果您使用的场景没有像桌面应用程序那样的回调,那么使用oauth客户端是可能的。在这种情况下,用户将需要手动将验证器复制回应用程序。这个场景也应该由Servcie支持(Upwork不支持它,请参见下面)。

Step 4. Use the 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中发送您的客户端密钥和访问令牌。请求与客户端秘密+访问令牌秘密进行签名。

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. You still need to perform the oauth steps from your application, the library will only help you with signing.

ote -1.0a允许您在node中签名请求。在客户端javascript中。您仍然需要执行来自应用程序的oauth步骤,库将只帮助您签名。

The code

I tested the Step 1 from the browser javascript and Upwork doesn't support this scenario. If I send the regular POST request with ajax, it returns the 'Access-Control-Allow-Originerror. And if I try this request usingJSONP`, Upwork responds with the 404 error.

我从浏览器javascript测试了步骤1,而Upwork不支持这个场景。如果我使用ajax发送常规的POST请求,它将返回“访问控制允许-初始错误”。如果我使用jsonp来尝试这个请求,Upwork会响应404错误。

So there is no JSONP support for the api/auth/v1/oauth/token/request endpoint.

因此,没有JSONP支持api/auth/v1/oauth/token/请求端点。

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):

下面是令牌请求的外观(步骤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. Requests are signed using oauth-1.0a.

注意,Upwork有nodejs库,但我并不是用它手工完成所有的事情。请求使用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. In the real-life scenario, your application will specify the oauth_callback parameter and Upwork will send the oauth verifier to your application. In this example I just manually copy it from the browser and pass to the next step.

第2步在浏览器中执行,这里您只需打开url,如“https://www.upwork.com/services/api/auth?”oauth_token=xxx',获取oauth验证符。在实际的场景中,应用程序将指定oauth_callback参数,Upwork将oauth验证器发送到应用程序。在本例中,我只是从浏览器手动复制它,然后传递到下一步。

Having the oauth verifier, you can get the permanent access token (Step 3):

有了oauth验证器,您可以获得永久访问令牌(步骤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,第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(尽管不是很好,因为需要将访问令牌和secret放入代码中)。

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=? to the request, but jQuery adds this parameter automatically when you set JSONP data type. 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:

它说要添加回调=?对于请求,但是在设置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);
      },
    });
};

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安装并启动节点。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:

现在打开测试。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}

#1


4  

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. Skip to the The code part if OAuth process is clear.

TLDR我将从OAuth 1.0过程描述开始,以确保下面的代码示例和我的结论是清晰的。如果OAuth过程是清晰的,跳过代码部分。

The OAuth 1.0 process

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.

This request is made by your App to the Service. Your App passes the client key, so the Service knows who asks.

这个请求是由您的应用程序提供给服务的。你的应用程序通过客户端密钥,这样服务就知道谁在问。

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).

该请求使用客户端秘密进行签名,该服务也有这个秘密,并可以验证它是否是来自您的应用程序的请求,而不是窃取您的客户端密钥的其他人的请求(这就是为什么您不应该向任何人透露您的秘密)。

Server returns the temporary oauth token + temporary oauth secret.

服务器返回临时oauth令牌+临时oauth秘密。

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.

Your application just redirects the user to the special URL provided by 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中的临时标记,因此服务知道哪个应用程序请求访问。

If you have a web-application, you just open this special url in the browser. The Service then redirects back to your App, using the oauth_callback (the URL to redirect the user back to). The Service also passes the oauth_verifier to the oauth_callback URL.

如果您有一个web应用程序,您只需在浏览器中打开这个特殊的url。然后,该服务使用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. In this case you set the oauth_calback to the special oob (out-of-band) value. 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.

如果您有一个桌面应用程序,它应该启动浏览器,服务可以将oauth_verifier显示为字符串,这样用户就可以手动复制并粘贴回应用程序。此部分(没有重定向返回)在规范中没有严格描述,因此细节取决于服务。它可能完全不被支持或以其他方式被支持。

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 = {临时令牌}

Step 3. Get the real oauth access token.

Your app sends the temporary token from the step 1 and oauth verifier from the step 2 to the Service. The request is again signed, but this time using the client secret and temporary token secret. Service responds with the access token + secret.

您的应用程序将第1步和oauth验证器的临时标记从步骤2发送到服务。再次对请求进行签名,但这一次使用客户端秘密和临时令牌秘密。服务响应访问令牌+秘密。

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. The example in the specification is also good and clear, check it.

这是获取真正访问并开始使用服务API的三个步骤。规范中的示例也很好很清楚,请检查。

Also note that the OAuth 1.0 can not be safely used in 100% client-side apps. 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). On the step 2 the Service will redirect the browser back to the oauth_callback and you can't handle it client-side.

还要注意,OAuth 1.0不能安全地用于100%的客户端应用程序。在步骤1中,您需要使用不应该被任何人知道的私有客户端秘密(因此您不能将其放入客户端代码中)。在步骤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. 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).

从技术上讲,如果您使用的场景没有像桌面应用程序那样的回调,那么使用oauth客户端是可能的。在这种情况下,用户将需要手动将验证器复制回应用程序。这个场景也应该由Servcie支持(Upwork不支持它,请参见下面)。

Step 4. Use the 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中发送您的客户端密钥和访问令牌。请求与客户端秘密+访问令牌秘密进行签名。

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. You still need to perform the oauth steps from your application, the library will only help you with signing.

ote -1.0a允许您在node中签名请求。在客户端javascript中。您仍然需要执行来自应用程序的oauth步骤,库将只帮助您签名。

The code

I tested the Step 1 from the browser javascript and Upwork doesn't support this scenario. If I send the regular POST request with ajax, it returns the 'Access-Control-Allow-Originerror. And if I try this request usingJSONP`, Upwork responds with the 404 error.

我从浏览器javascript测试了步骤1,而Upwork不支持这个场景。如果我使用ajax发送常规的POST请求,它将返回“访问控制允许-初始错误”。如果我使用jsonp来尝试这个请求,Upwork会响应404错误。

So there is no JSONP support for the api/auth/v1/oauth/token/request endpoint.

因此,没有JSONP支持api/auth/v1/oauth/token/请求端点。

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):

下面是令牌请求的外观(步骤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. Requests are signed using oauth-1.0a.

注意,Upwork有nodejs库,但我并不是用它手工完成所有的事情。请求使用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. In the real-life scenario, your application will specify the oauth_callback parameter and Upwork will send the oauth verifier to your application. In this example I just manually copy it from the browser and pass to the next step.

第2步在浏览器中执行,这里您只需打开url,如“https://www.upwork.com/services/api/auth?”oauth_token=xxx',获取oauth验证符。在实际的场景中,应用程序将指定oauth_callback参数,Upwork将oauth验证器发送到应用程序。在本例中,我只是从浏览器手动复制它,然后传递到下一步。

Having the oauth verifier, you can get the permanent access token (Step 3):

有了oauth验证器,您可以获得永久访问令牌(步骤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,第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(尽管不是很好,因为需要将访问令牌和secret放入代码中)。

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=? to the request, but jQuery adds this parameter automatically when you set JSONP data type. 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:

它说要添加回调=?对于请求,但是在设置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);
      },
    });
};

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安装并启动节点。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:

现在打开测试。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}