为什么我不能使用命令行curl为LinkedIn API生成有效的oauth-token?

zea*_*ker 6 curl oauth linkedin meteor

在测试LinkedIn API并尝试构建Meteor JS智能包以对LinkedIn的OAuth提供商进行身份验证时,我遇到了一个完全障碍.

在遵循这些指示的过程中,我能够成功生成一个oauth_token用于授权请求的形式,其形式为:

https://www.linkedin.com/uas/oauth/authorize?oauth_token={oauth_token}
Run Code Online (Sandbox Code Playgroud)

当使用由如下所示的ruby脚本生成的令牌将其放入浏览器时:

require 'oauth'

api_key = '{linkedin api key}'
api_secret = '{linkedin api secret}'

configuration = { :site => 'https://api.linkedin.com',
                          :authorize_path => '/uas/oauth/authenticate',
                          :request_token_path => '/uas/oauth/requestToken',
                          :access_token_path => '/uas/oauth/accessToken' }

consumer = OAuth::Consumer.new(api_key, api_secret, configuration)

request_token = consumer.get_request_token
puts request_token.params[:oauth_token]
Run Code Online (Sandbox Code Playgroud)

然后,我可以使用上面的URI轻松地将令牌转储为浏览器中的查询字符串参数,并查看LinkedIn权限对话框.

使用有效令牌显示的LinkedIn auth窗口: 在此输入图像描述

不幸的是,当尝试在命令行中编写curl请求时,oauth_token生成的请求在同一个url中使用时会失败.实际上,它导致linkedin以500错误响应,并且浏览器显示标准500错误窗口.响应没有附加细节:

500错误

这里的代码类似于我在我的curl请求中实现的新代码oauth_token:

alex@alex-mac accounts-linkedin (fixes_for_meteor_0_5_4)* $ cat linkedin_oauth_gen.sh 

curl -X POST https://api.linkedin.com/uas/oauth/requestToken --verbose --header 'Authorization: OAuth oauth_nonce="0d9a3e40660811e2bcfd0800200c9a66",oauth_timestamp="1359019570",oauth_version="1.0",oauth_signature_method="HMAC-SHA1",oauth_consumer_key="{oauth_consumer_key}",oauth_signature="{oauth_signature}"'
Run Code Online (Sandbox Code Playgroud)

值得注意的是,我使用了LinkedIn的OAuth测试控制台来生成Authorization标头.

这很重要,因为我在尝试在Meteor JS智能包中实现类似功能时会遇到同样的问题.

然而,我的主要问题是为什么在世界上我可以用上面的ruby代码来做,但是当使用简单的curl shell命令时,令牌似乎没有有效生成(或者LinkedIn根本不想尊重它) ...

zea*_*ker 5

像往常一样,魔鬼是最微小的细节.

在解决这个问题时,我使用了精彩的Charles Proxy来监视我的ruby脚本通过oauth库发出的请求.

事实证明我有两个不同的问题,我试图通过查看成功的ruby请求发现curl和meteor的请求,同时回顾我的代码并弄乱oauth_callbackAuthorization头参数来反向设计问题.

这些问题中的任何一个或组合都会导致生成无效且无法识别的oauth令牌.不会返回401,而是生成令牌!唉,这个令牌毫无用处.

以下是2个不同的请求授权标头,这些标头失败(每个请求授权标头):

Authorization: OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="http%3A%2F%2Flocalhost%3A3000%2F_oauth%2Flinkedin%3Fclose", oauth_consumer_key="*********", oauth_nonce="SJ3DSTHLh0T4UcqzYOUOqubIeWN9FERCePm5ro35EY", oauth_signature="*********", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1359081520", oauth_version="1.0"
Run Code Online (Sandbox Code Playgroud)

在第一个例子中,问题是oauth_callbackparam有一个格式错误的查询字符串参数.事实证明,拥有一个?close没有值的查询字符串参数,如同?close=true,导致请求完全成熟.我仍然不知道为什么,但似乎是这种情况.

Authorization: OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="http%3A%2F%2Flocalhost%3A3000%2F_oauth%2Flinkedin%3Fclose", oauth_consumer_key="*********", oauth_nonce="SJ3DSTHLh0T4UcqzYOUOqubIeWN9FERCePm5ro35EY", oauth_signature="*********", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1359081520", oauth_version="1.0"
Run Code Online (Sandbox Code Playgroud)

在此第二实例中,问题是,oauth_callback具有localhost在其领域.事实证明,一些oauth提供者,其中一个是,不喜欢oauth_callbackparam中的主机名(与FQDN或IP地址相对).打败我为什么.我们需要使用127.0.0.1.有没有很好的理由,但它只是.瘸子,但是真的.

这个工作:

Authorization: OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="http%3A%2F%2F127.0.0.1%3A3000%2F_oauth%2Flinkedin%3Fclose%3Dtrue%26state%3D0e314d0d-a5ca-40ca-8fcd-caa1cfce3ed4", oauth_consumer_key="*********", oauth_nonce="0KBnMSMI8NNk1cXn0YyTRpUnPdnqAX7F06KEloh9bs", oauth_signature="*********", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1359082177", oauth_version="1.0"
Run Code Online (Sandbox Code Playgroud)

注意:为了保护我的密钥和消除对我的秘密进行逆向工程的可能性,我已经替换oauth_consumer_keyoauth_signature重视了值*********.