2

oauth 1.0 を介して 500px API への認証済みリクエストを行う必要があります。私はこのガイドに従っていて、説明されているワークフローをいくつかの異なる方法で実装しましたが、取得し続けていstatusCode: 401...ます.

OAuth リクエストの作成方法は次のとおりです。 ここに画像の説明を入力

ここで私がこれまでに試したこと:

試み #1:

likePhoto (id) {
  let crypto = Npm.require('crypto'),
    consumerKey = '-',
    consumerSecret = '-',
    accessToken = Meteor.user().services.Fivehundredpx.accessToken,
    accessTokenSecret = Meteor.user().services.Fivehundredpx.accessTokenSecret,

    url  = 'https://api.500px.com/v1/photos/231034201/vote?vote=1',
    date = new Date,
    method = 'POST';


  // Note that the keys are in alphabetical order
  let reqObj = {
    oauth_consumer_key: consumerKey,
    oauth_nonce: Math.random().toString(36).replace(/[^a-z]/, '').substr(2),
    oauth_signature_method: 'HMAC-SHA1',
    oauth_timestamp: Math.floor(date.getTime() / 1000),
    oauth_token: accessToken,
    oauth_version: '1.0'
  };

  // construct a param=value& string and uriEncode
  let paramsStr = '';
  for (let i in reqObj) {
    paramsStr += "&" + i + "=" + reqObj[i];
  }

  // yank off that first "&"
  paramsStr = paramsStr.substr(1);

  let sigBaseStr = method + "&" + encodeURIComponent(url) + "&" + encodeURIComponent(paramsStr);

  consumerSecret += "&" + accessTokenSecret;

  let hashedBaseStr  = crypto.createHmac('sha1', consumerSecret).update(sigBaseStr).digest('base64');

  // Add oauth_signature to the request object
  reqObj.oauth_signature = encodeURIComponent(hashedBaseStr);

  let authorization = 'OAuth ';
  for (let i in reqObj) {
    authorization += i + '="'+ reqObj[i] + '",';
  }

  console.log(authorization);
  Meteor.http.call(method, url,
    {headers: {
      Authorization: authorization,
    }},
    function (error, result) {
      console.log(result || error);
    });
}

試み #2:

likePhoto (id) {
  const oauthSignature = require('oauth-signature');
  let date = new Date;
  let httpMethod = 'POST',
    url = 'https://api.500px.com/v1/photos/231034201/vote?vote=1',
    parameters = {
      oauth_consumer_key : '',
      oauth_nonce : Math.random().toString(36).replace(/[^a-z]/, '').substr(2),
      oauth_signature_method : 'HMAC-SHA1',
      oauth_timestamp : Math.floor(date.getTime() / 1000),
      oauth_token : Meteor.user().services.Fivehundredpx.accessToken,
      oauth_version : '1.0',
    },
    consumerSecret = '',
    tokenSecret = Meteor.user().services.Fivehundredpx.accessTokenSecret,

    // generates a RFC 3986 encoded, BASE64 encoded HMAC-SHA1 hash
    encodedSignature = oauthSignature.generate(httpMethod, url, parameters, consumerSecret, tokenSecret),
    // generates a BASE64 encode HMAC-SHA1 hчash
    signature = oauthSignature.generate(httpMethod, url, parameters, consumerSecret, tokenSecret,
      { encodeSignature: false});


  // construct a param=value& string and uriEncode
  let paramsStr = '';
  for (let i in parameters) {
    paramsStr += "&" + i + "=" + parameters[i];
  }

  // Add oauth_signature to the request object
  parameters.oauth_signature = encodedSignature;

  let authorization = 'OAuth ';
  for (let i in parameters) {
    authorization += i + '="'+ parameters[i] + '",';
  }

  console.log(authorization);
  HTTP.call(httpMethod, url,
    {
      headers: {
        'Authorization': authorization,
      }
    },
    function (error, result) {
      console.log(result || error);
    });
}

試行 #3:

function oAuthBaseString(method, url, params, key, token, timestamp, nonce) {
  return method
    + '&' + percentEncode(url)
    + '&' + percentEncode(genSortedParamStr(params, key, token, timestamp, nonce));
}

function oAuthSigningKey(consumer_secret, token_secret) {
  return consumer_secret + '&' + token_secret;
}

function oAuthSignature(base_string, signing_key) {
  var signature = hmac_sha1(base_string, signing_key);
  return percentEncode(signature);
}


// Percent encoding
function percentEncode(str) {
  return encodeURIComponent(str).replace(/[!*()']/g, (character) => {
    return '%' + character.charCodeAt(0).toString(16);
  });
}


// HMAC-SHA1 Encoding, uses jsSHA lib
var jsSHA = require('jssha');
function hmac_sha1(string, secret) {
  let shaObj = new jsSHA("SHA-1", "TEXT");
  shaObj.setHMACKey(secret, "TEXT");
  shaObj.update(string);
  let hmac = shaObj.getHMAC("B64");
  return hmac;
}


// Merge two objects
function mergeObjs(obj1, obj2) {
  for (var attr in obj2) {
    obj1[attr] = obj2[attr];
  }
  return obj1;
}


// Generate Sorted Parameter String for base string params
function genSortedParamStr(params, key, token, timestamp, nonce)  {
  // Merge oauth params & request params to single object
  let paramObj = mergeObjs(
    {
      oauth_consumer_key : key,
      oauth_nonce : nonce,
      oauth_signature_method : 'HMAC-SHA1',
      oauth_timestamp : timestamp,
      oauth_token : token,
      oauth_version : '1.0'
    },
    params
  );
  // Sort alphabetically
  let paramObjKeys = Object.keys(paramObj);
  let len = paramObjKeys.length;
  paramObjKeys.sort();
  // Interpolate to string with format as key1=val1&key2=val2&...
  let paramStr = paramObjKeys[0] + '=' + paramObj[paramObjKeys[0]];
  for (var i = 1; i < len; i++) {
    paramStr += '&' + paramObjKeys[i] + '=' + percentEncode(decodeURIComponent(paramObj[paramObjKeys[i]]));
  }
  return paramStr;
}

likePhoto (id) {
    const btoa = require('btoa');
    // Get acces keys
    const consumerKey       = '-',
      consumerSecret      = '-',
      accessToken         = Meteor.user().services.Fivehundredpx.accessToken,
      accessTokenSecret   = Meteor.user().services.Fivehundredpx.accessTokenSecret;
    // timestamp as unix epoch
    let timestamp  = Math.round(Date.now() / 1000);
    // nonce as base64 encoded unique random string
    let nonce      = btoa(consumerKey + ':' + timestamp);
    // generate signature from base string & signing key
    let httpMethod = 'POST';
    let baseUrl = 'https://api.500px.com/v1/photos/231034201/vote?vote=1';
    let reqParams = '';
    let baseString = oAuthBaseString(httpMethod, baseUrl, reqParams, consumerKey, accessToken, timestamp, nonce);
    let signingKey = oAuthSigningKey(consumerSecret, accessTokenSecret);
    let signature  = oAuthSignature(baseString, signingKey);
    // return interpolated string
    let authorization = 'OAuth ' +
      'oauth_consumer_key="'  + consumerKey       + '", ' +
      'oauth_nonce="'         + nonce             + '", ' +
      'oauth_signature="'     + signature         + '", ' +
      'oauth_signature_method="HMAC-SHA1", '              +
      'oauth_timestamp="'     + timestamp         + '", ' +
      'oauth_token="'         + accessToken       + '", ' +
      'oauth_version="1.0"';

    console.log(authorization);
    HTTP.call(httpMethod, baseUrl,
      {headers: {
        Authorization: authorization,
      }},
      function (error, result) {
        console.log(result || error);
      });
  }

このAPI クライアントをテストに使用していますが、すべてのリクエストは正常に機能しています。同様のワークフローとコードを使用して別の OAuth 1.0 認証リクエストを実装したところ、うまくいきましたが、私の側では間違いであるはずです。

エラーメッセージ:

{ 
  statusCode: 401,
  content: '',
  headers: 
  { date: 'Mon, 09 Oct 2017 05:27:17 GMT',
    'content-type': 'text/html',
    'transfer-encoding': 'chunked',
    connection: 'close',
    status: '401 Unauthorized',
    'x-xss-protection': '1; mode=block',
    'x-content-type-options': 'nosniff',
    'cache-control': 'no-cache',
    'set-cookie': 
    [ 'device_uuid=4b97d884-b24e-413c-90ee-60d11e7f2ad7; path=/; expires=Fri, 09 Oct 2037 05:27:17 -0000',
    '_hpx1=BAh7B0kiD3Nlc3Npb25faWQGOgZFVEkiJWE2MDVmYmUyZjBkODlmNGFhYmM5MjM5OGEwNjU2NzI5BjsAVEkiCWhvc3QGOwBGIhJhcGkuNTAwcHguY29t--aa2897a2b8ee32b650e0d830d51882e5ac8208cb; domain=.500px.com; path=/; HttpOnly' ],
    'x-request-id': '7e13f562-2525-472c-9b80-9870905e6eea',
    'x-runtime': '0.011553',
    'x-rack-cache': 'invalidate, pass',
    server: 'api20-ovh-bhs'
    },
  data: null 
}
4

1 に答える 1