我是新来的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}