Invalid signature when attempting to receive token

73 views
Skip to first unread message

Christian Burtchen

unread,
Apr 5, 2021, 10:51:04 AM4/5/21
to Etsy API
Hello everyone,

I've been spending the last week trying to get the OAuth flow to work in pure JS. I looked at various examples, including of course the official documentation of both the Etsy API and the Oauth 1.0 spec, and thought I had it, yet I keep getting an invalid signature 401 request, so I think I might be missing something obvious. Would appreciate any hints/rubberducking.

My code is as follows:

const oauth_timestamp = Math.floor(Date.now() / 1000);
const oauth_nonce = v1(); // uuid vs

const urlRoot = "https://openapi.etsy.com/v2/oauth/request_token";

const parameters = `scope=listings_r&oauth_consumer_key=${encodeURIComponent(
      API_KEY
    )}&oauth_consumer_secret=${encodeURIComponent(
      API_SECRET
    )}&oauth_timestamp=${oauth_timestamp}&oauth_nonce=${encodeURIComponent(
      oauth_nonce
    )}&oauth_signature_method=${encodeURIComponent("HMAC-SHA1")}`;

const basicString = `GET&${encodeURIComponent(urlRoot)}&${encodeURIComponent(parameters)}`; // the basicString used for the signature generation, based on what I found here https://oauth1.wp-api.org/docs/basics/Signing.html and here https://pandeysoni.medium.com/how-to-create-oauth-1-0a-signature-in-node-js-7d477dead170

const enc = new TextEncoder("utf-8");

window.crypto.subtle
      .importKey(
        "raw",
        enc.encode(API_SECRET),
        {
          name: "HMAC",
          hash: { name: "SHA-1" },
        },
        false,
        ["sign", "verify"]
      )
      .then((key) => {
        window.crypto.subtle
          .sign("HMAC", key, enc.encode(basicString))
          .then((signature) => {
            const b = new Uint8Array(signature);
            const oauth_signature = Array.prototype.map
              .call(b, (x) => ("00" + x.toString(16)).slice(-2))
              .join("");
           // the "oauth_signature" here is equivalent to what online HMAC-SHA1 generators had
            fetch(
     `${urlRoot}?${parameters}&oauth_signature=${encodeURIComponent(
                btoa(oauth_signature) // also tried without btoa
              )}`,
              {
                method: "GET",
                mode: "no-cors",
              }
            );
          });
      });

I would appreciate any pointers to what I'm doing wrong!
Reply all
Reply to author
Forward
0 new messages