如何解决Postman Oauth 1.0 签名与我在 Perl 中得到的不匹配
我正在尝试通过 Oauth 1.0 对 Here.com API 进行身份验证。我有一个成功获取身份验证令牌的有效 Postman 请求。我尝试在 Perl 中实现签名生成过程,但我得到的签名与 Postman 得到的签名不同。我还使用相同的参数检查了 this sandbox,它似乎生成了与我得到的签名相同的签名,但是这个签名失败了,而 Postman 生成的签名成功了,老实说,我无法弄清楚为什么。让我分享一些例子:
这是我在 Perl 中使用的代码,带有测试参数:
use URI::Encode;
use Digest::SHA qw(hmac_sha256 hmac_sha1 hmac_sha256_base64);
use MIME::Base64;
my $oauth_values = {
consumer_key => "my-test-key",consumer_secret => "my-test-secret",request_url => "https://account.api.here.com/oauth2/token",request_method => "POST",signature_method => "HMAC-SHA256",timestamp => 1234567890,nonce => "test-nonce",protocol_version => "1.0",};
my $encoder = URI::Encode->new( { encode_reserved => 1 } );
my $signature_base_string = "oauth_consumer_key=$oauth_values->{consumer_key}" .
"&oauth_nonce=$oauth_values->{nonce}" .
"&oauth_signature_method=$oauth_values->{signature_method}" .
"&oauth_timestamp=$oauth_values->{timestamp}" .
"&oauth_version=$oauth_values->{protocol_version}";
my $base_string = "POST&" . $encoder->encode($oauth_values->{request_url}) . "&" . $encoder->encode($signature_base_string);
print "Signature base string: $signature_base_string\n";
print "Base string: $base_string\n";
my $signature = encode_base64(hmac_sha256($base_string,$oauth_values->{consumer_secret} . "&"));
print "Signature: $signature\n";
请注意,基本字符串上的参数按字母顺序排列,这是应该的。
Signature base string: oauth_consumer_key=my-test-key&oauth_nonce=test-nonce&oauth_signature_method=HMAC-SHA256&oauth_timestamp=1234567890&oauth_version=1.0
Base string: POST&https%3A%2F%2Faccount.api.here.com%2Foauth2%2Ftoken&oauth_consumer_key%3Dmy-test-key%26oauth_nonce%3Dtest-nonce%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1234567890%26oauth_version%3D1.0
Signature: KOXTa8e/Vw083CAwZctnZiJVIvAjH1aw4/5RWXeIhX4=
如果我将这些相同的参数放在 the sandbox 上,我会得到相同的签名: sandbox signature screenshot
但是,当我在 Postman 中放入完全相同的参数时: Postman parameter settings
那么Postman生成的签名就不一样了:
OxhDiuqUEBAd45vNn4zIy/0etSVOn2fvquw+kQMxwsg=
import requests
url = "https://account.api.here.com/oauth2/token"
payload = ""
headers = {
'Authorization': 'OAuth oauth_consumer_key="my-test-key",oauth_signature_method="HMAC-SHA256",oauth_timestamp="1234567890",oauth_nonce="test-nonce",oauth_version="1.0",oauth_signature="OxhDiuqUEBAd45vNn4zIy/0etSVOn2fvquw+kQMxwsg="'
}
response = requests.request("POST",url,headers=headers,data=payload)
print(response.text)
我什至阅读了 RFC with the steps,但我没有发现我的方法中有错误。
为什么 Postman 签名是正确的,而我生成的却不是?我错过了什么或做错了什么?
解决方法
我能够弄清楚。事实证明,encode_base64
在末尾添加了一个新行,这破坏了我在请求中发送的签名。修复后立即添加 chomp
。
此外,我在 Postman 和 Perl 签名之间得到的差异是由于 Postman 在参数化 URL 时计算基本字符串的方式,显然,因为切换到“硬编码”URL 使签名一致。令人惊讶的是,在这两种情况下,Postman 都能够获得一个身份验证令牌,这让我认为当我查看 Postman 中的“代码”选项时我得到的签名不一定与请求中发送的签名相同。
简而言之,这样做是有效的:
my $digest = encode_base64(hmac_sha256($base_string,$oauth_values->{consumer_secret} . "&"));
chomp $digest;
my $signature_encoded = $encoder->encode($digest);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。