我是新来的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"); },});
CodePen:http://codepen.io/nunoarruda/pen/xZBEzB?editors=1010
提前致谢!
解决方法
如果OAuth进程清楚,请跳到代码部分.
OAuth 1.0进程
我使用以下术语(它们与官方术语不同,但希望能使事情更清楚):
应用程序 – 您的应用程序
>服务 – 您要求数据的服务
>用户 – 给您访问由本服务存储的数据的用户
制备.在服务中注册您的应用程序
您将获得用于启动Outh进程的客户端密钥和密码.
在Upwork的情况下,你可以这样做 – https://www.upwork.com/services/api/apply.
步骤1.获取临时的oauth令牌.
此请求由您的应用程序发送到服务.
您的应用程序通过客户端密钥,因此该服务知道谁询问.
该请求使用客户机密码进行签名,该服务也具有该功能,并可以确认它是否实际是您的应用程序的请求,而不是来自窃取客户端密钥的其他人员(这是您不应该向您显示您的秘密的原因任何人).
服务器返回临时oauth令牌临时oauth机密.
在Upwork的情况下,您将此请求发送到https://www.upwork.com/api/auth/v1/oauth/token/request
请求用户授予您访问权限.
该服务显示一个对话框,用户可以为您的应用程序提供访问权限.
该特殊URL包括步骤1中的临时令牌,因此该服务知道哪个应用程序要求访问.
如果您有一个Web应用程序,您只需在浏览器中打开此特殊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= {临时令牌}
获取真实的oauth访问令牌.
您的应用程序将步骤1和oauth验证程序的临时令牌从步骤2发送到服务.
请求再次签名,但这次使用客户端的秘密和临时令牌秘密.
服务使用访问令牌秘密进行响应.
在Upwork的情况下,URL为https://www.upwork.com/api/auth/v1/oauth/token/access
这三个步骤可以获得真正的访问权限并开始使用Service API.
规范中的例子也很好,很清楚,check it.
另请注意,OAuth 1.0无法在100%客户端应用程序中安全使用.
在步骤1中,您需要使用私人客户机密码(不应该被任何人知晓)(因此您不得将其放入客户端代码).
在步骤2上,服务将将浏览器重定向到oauth_callback,您无法处理客户端.
如果在桌面应用程序中使用没有回调的场景,那么技术上可以使用oauth客户端.在这种情况下,用户需要手动将验证者复制回应用程序.
这种情况也应该由Servcie(Upwork不支持,见下文)支持.
步骤4.使用Service API
现在,一旦获得访问令牌,您可以获取API请求来获取数据,此处,您将从步骤3发送客户端密钥和访问令牌.
使用客户端密码访问令牌秘密签名请求.
过程中最复杂的部分是请求签名,它在规范中有详细介绍,但这是使用库最好的地方.
oauth-1.0a允许您在node.js和客户端JavaScript中签署您的请求.
您仍然需要从您的应用程序执行oauth步骤,该库仅帮助您进行签名.
我从浏览器javascript测试了第1步,Upwork不支持这种情况.
如果我使用ajax发送常规POST请求,则返回“Access-Control-Allow-Originerror”.如果我使用JSONP`尝试这个请求,Upwork会回应404错误.
因此,api / auth / v1 / oauth / token / request端点没有JSONP支持.
步骤1-3应该使用服务器端(无论如何,客户端认证将是不安全的).
以下是令牌请求的外观(步骤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); }); };
请注意,Upwork具有nodejs library,但是我并没有使用它来手动执行所有操作.
请求使用oauth-1.0a签名.
步骤2在浏览器中执行,这里您只需打开像’https://www.upwork.com/services/api/auth?oauth_token=xxx‘这样的URL,并获得oauth验证器.
在现实情况下,您的应用程序将指定oauth_callback参数,Upwork会将oauth验证器发送到您的应用程序.
在这个例子中,我只是从浏览器手动复制它并转到下一步.
拥有oauth验证者,您可以获得永久访问令牌(步骤3):
oauthTest.step3_accessToken = function(oauth_verifier) { var request_data = { url: 'https://www.upwork.com/api/auth/v1/oauth/token/access',data: { oauth_verifier: oauth_verifier } }; request({ url: request_data.url,form: oauthTest.oauth.authorize(request_data,oauthTest.tempToken) // use the temp token },body) { var data = qs.parse(body); console.log(data); }); };
最后,您可以使用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,qs: oauthTest.oauth.authorize(request_data,oauthTest.accessToken) // use the access token },body) { console.log(body); }); };
可以从客户端使用API(虽然不好,因为您需要将访问令牌和密码放入代码中).
解决方案是棘手的,因为文档(https://developers.upwork.com/?lang=node#getting-started_cross-domain-requests)不完整,并不完全正确.
它说要添加回调=?请求,但是jQuery在设置JSONP数据类型时会自动添加此参数.此外,参数值设置为一些随机字符串,所以我认为这个参数不应该被签名,但它似乎应该:
function queryAPI(public,secret) { var accessToken = { public: public,secret: secret } var request_data = { url: 'https://www.upwork.com/api/profiles/v2/search/jobs.json',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,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并启动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}