6

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

按照这些指示,我能够成功地生成一个oauth_token用于授权请求的格式,格式为:

https://www.linkedin.com/uas/oauth/authorize?oauth_token={oauth_token}

当使用由如下所示的 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]

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

使用有效令牌显示的 LinkedIn 身份验证窗口: 在此处输入图像描述

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

500 错误

这是类似于我在 curl 请求中实现的代码,以获取 new 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}"'

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

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

然而,我的主要问题是,为什么我可以用上面的 ruby​​ 代码做到这一点,但是当使用简单的 curl shell 命令时,令牌似乎没有有效生成(或者 LinkedIn 根本不想兑现它) ...

4

1 回答 1

5

像往常一样,魔鬼藏在最微小的细节中。

在解决这个问题时,我使用了非常棒的Charles Proxy来监视我的 ruby​​ 脚本通过 oauth 库发出的请求。

事实证明,我如何尝试从 curl 和来自流星的请求存在两个oauth_callback明显的问题,我通过在查看我的代码并弄乱Authorization 标头参数以对问题进行逆向工程时监视成功的 ruby​​ 请求而发现了这两个问题.

这些问题之一或组合导致生成无效且无法识别的 oauth 令牌。linkedin 没有返回 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"

在第一个示例中,问题在于oauth_callback参数具有格式错误的查询字符串参数。事实证明,有一个?close没有值的查询字符串参数,如 in ?close=true,会导致请求完全被 fubared。我仍然不知道确切原因,但似乎是这样。

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"

在第二个示例中,问题在于oauth_callbacklocalhost的域中。事实证明,一些 oauth 提供者,linkedin 是其中之一,不喜欢oauth_callback参数中的主机名(与 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"

注意:出于保护我的密钥和消除对我的秘密进行逆向工程的可能性的明显原因,我已经替换了oauth_consumer_keyoauth_signature值。*********

于 2013-01-25T03:15:25.577 回答