Question

I'm getting this problem with my app in perl for oauth authentication:

401 Unauthorized Failed to validate oauth signature and token

Here is my code:

sub Twitter {

my $IN = new CGI;

  my $qs = build_query({
    oauth_callback => $callback_url,
    oauth_consumer_key => $consumer_key,
    oauth_nonce => time,
    oauth_signature_method => "HMAC-SHA1",
    oauth_timestamp => time,
    oauth_version => "1.0"
  });

# Create Signature

  my $signing_key = $IN->escape($consumer_secret)."&";

  my $base_signature = "POST&".$IN->escape($request_token_url)."&".$qs;

  use Digest::HMAC_SHA1;

  my $hmac = Digest::HMAC_SHA1->new($signing_key);
  $hmac->add($base_signature);

  $qs .= "&oauth_signature=".$IN->escape($hmac->b64digest);

# Fetch the page

  use LWP;
  my $ua = LWP::UserAgent->new;
  my $req = HTTP::Request->new(POST => $request_token_url);
  $req->content_type('application/x-www-form-urlencoded');
  $req->content($qs);

  my $res = $ua->request($req);

# Check the outcome of the response
  unless ($res->is_success) {
    print $IN->header.$res->status_line, "\n";
    print $res->content;
    exit;
  }
  print $IN->header.$res->content;
}
sub build_query {
  my $input = shift;
  use URI;
  my $uri = URI->new;
  $uri->query_form($input);
  return $uri->query;
}

I have obviously deleted my callback url and key information.

Was it helpful?

Solution

I figured it out. I was encoding the signature wrong, I had to sort my query strings, and the call back URL is not needed in this instance. Here is my working code:

sub Twitter {

  my $IN = new CGI;

  my $params = {
    oauth_consumer_key => $consumer_key,
    oauth_nonce => time,
    oauth_signature_method => "HMAC-SHA1",
    oauth_timestamp => time,
    oauth_version => "1.0"
  };
  my $qs = build_sorted_query($params);

  my $signing_key = $IN->escape($consumer_secret)."&";

  my $signature_base = "POST&".$IN->escape($request_token_url)."&".$IN->escape($qs);

  use Digest::HMAC_SHA1;
  use MIME::Base64;

  my $hmac = Digest::HMAC_SHA1->new($signing_key);
  $hmac->add($signature_base);

  $params->{oauth_signature} = $IN->escape(encode_base64($hmac->digest));

  $qs = build_sorted_query($params);

  use LWP;
  my $ua = LWP::UserAgent->new;
  my $req = HTTP::Request->new(POST => $request_token_url);
  $req->content_type('application/x-www-form-urlencoded');
  $req->content($qs);

  my $res = $ua->request($req);

# Check the outcome of the response
  unless ($res->is_success) {
    print $IN->header.$res->status_line, "\n";
    print $res->content;
    exit;
  }
  print $IN->header.$res->content;
  return;
}
sub build_sorted_query {
  my $input = shift;
  my $qs;
  foreach (sort keys %$input) {
      $qs .= $_."=".$input->{$_}."&";
  }
  return substr ($qs, 0, -1);
}

Thanks for looking!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top