当前位置: 首页 > 知识库问答 >
问题:

使用Oauth 1.0获取Twitter request\u令牌的尝试不断出现“215错误身份验证”错误

刁俊人
2023-03-14

我正在尝试从Twitter获取Oauth请求令牌-我遵循他们的指南(下面的链接),我已经将每一步都检查了大约10次,但我不明白为什么会出现此错误:

{“errors\”:[{“code\”:32,\“message\”:\“无法对您进行身份验证。\”}]}

他们使用Oauth 1.0。我应该将请求中的所有百分比编码参数组合在一起,对它们进行百分比编码,添加请求方法(POST)和请求url,使用该方法加上我的api密钥机密创建签名,然后将签名添加到我的最终POST请求中。签名文档在此页面上,后续的请求后文档在此页面上。我使用指南中给出的示例代码生成签名,得到了与指南相同的结果,因此我不认为实际的签名生成是一个问题。

我三次检查了我的api密钥、api密钥密钥和回调url。

这是我的全部代码。有人能看到问题吗?

require 'net/http'
require 'uri'
require 'json'
require 'base64'
require 'cgi'
require 'openssl'

oauth_callback = "http://www.example.localhost:3000/twittercallback"
oauth_consumer_key = '[KEY]'
oauth_timestamp = Time.now.to_i
oauth_nonce = SecureRandom.hex(10) + oauth_timestamp.to_s
oauth_signature_method = "HMAC-SHA1"
oauth_version = "1.0"


one1 = CGI.escape "oauth_callback"
one2 = CGI.escape oauth_callback
two1 = CGI.escape "oauth_consumer_key"
two2 = CGI.escape oauth_consumer_key
three1 = CGI.escape "oauth_nonce"
three2 = CGI.escape oauth_nonce
four1 = CGI.escape "oauth_signature_method"
four2 = CGI.escape oauth_signature_method
five1 = CGI.escape "oauth_timestamp"
five2 = CGI.escape oauth_timestamp.to_s
six1 = CGI.escape "oauth_version"
six2 = CGI.escape oauth_version
string = "#{one1}=#{one2}&#{two1}=#{two2}&#{three1}=#{three2}&#{four1}=#{four2}&#{five1}=#{five2}&#{six1}=#{six2}"
encoded_string = CGI.escape string
url = "https://api.twitter.com/oauth/request_token"
encoded_url = CGI.escape url
encoded_string = "POST&" + encoded_url + "&" + encoded_string
signing_key = '[SECRET]'
encoded_signing_key = (CGI.escape signing_key) + "&"
digest = OpenSSL::Digest::Digest.new( 'sha1' )
hmac = OpenSSL::HMAC.digest( digest, encoded_signing_key, encoded_string)
signature = Base64.encode64( hmac ).chomp.gsub( /\n/, '' )

uri = URI.parse("https://api.twitter.com/oauth/request_token")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/x-www-form-urlencoded"
oauth = 'OAuth oauth_callback="' + (CGI.escape oauth_callback) + '", oauth_nonce="' + (oauth_nonce + 'dsd') + '", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' + oauth_timestamp.to_s + '", oauth_consumer_key="`<KEY>", oauth_signature="' + (CGI.escape signature) + '", oauth_version="1.0"'
request['Authorization'] = oauth
request.body = ""
req_options = {
    use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
    http.request(request)
end

这是我的请求[“授权”]标题

"OAuthoauth_callback=\"http://www.example.localhost:3000/twittercallback\",oauth_nonce=\"e5686f142ca58a45af233fb66876671592457549dsd\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1592457549\",oauth_consumer_key=\"[KEY]\",oauth_signature=\"n9MNLO/t/T6WX0Myu5JcTICXNAQ=\",oauth_version=\"1.0\""

这是推特文档的标题示例:

OAuth OAuth\u nonce=“k7ny27jtpkvstgdylddfmqwvlerj2zak5bslrsqyw”,OAuth\u回调=”http://myapp.com:3005/twitter/process_callback“,oauth\u signature\u method=“HMAC-SHA1”,oauth\u timestamp=“1300228849”,oauth\u consumer\u key=“OQJEAFRSF11JBMSTRZZ”,oauth\u signature=“Pc+MLdv028fxCErFyi8KXFM+ddU=”,oauth\u version=“1.0”

共有1个答案

佘飞鸣
2023-03-14

您不提供所需的Authoration标头,而是为每个参数提供单独的标头。您需要将以下形式的参数组合为字符串,首先是OAuth

OAuth oauth_nonce="K7ny27JTpKVsTgdyLdDfmQQWVLERj2zAK5BslRsqyw",oauth_callback="http%3A%2F%2Fmyapp.com%3A3005%2Ftwitter%2Fprocess_callback",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1300228849",oauth_consumer_key="OqEqJeafRSF11jBMStrZz",oauth_signature="Pc%2BMLdv028fxCErFyi8KXFM%2BddU%3D",oauth_version="1.0"

并在授权标题中提供:

request['Authorization'] = <OAuth string>

您的代码中还有很多其他问题导致它无法工作:

  • 参数转义错误
  • 转义签名密钥
  • 将dsd添加到授权标题中的当前时间
  • 授权标头中的数据顺序错误(需要按字典顺序排列,例如,对于大多数库,按字母顺序排列)

因此,如果我们返工您的代码,将导致以下结果:

require 'net/http'
require 'uri'
require 'base64'
require 'cgi'
require 'openssl'
require 'securerandom'

oauth_consumer_key = CGI::escape('D6O7BIWc6MTgl0A8UaRRt83In')
oauth_timestamp = CGI::escape(Time.now.to_i.to_s)
oauth_nonce = CGI::escape(SecureRandom.hex(10) + oauth_timestamp.to_s)
oauth_signature_method = CGI::escape("HMAC-SHA1")
oauth_version = CGI::escape("1.0")

one1 = CGI::escape("oauth_consumer_key")
one2 = oauth_consumer_key
two1 = CGI::escape("oauth_nonce")
two2 = oauth_nonce
three1 = CGI::escape("oauth_signature_method")
three2 = oauth_signature_method
four1 = CGI::escape("oauth_timestamp")
four2 = oauth_timestamp
five1 = CGI::escape("oauth_version")
five2 = oauth_version
string = "#{one1}=#{one2}&#{two1}=#{two2}&#{three1}=#{three2}&#{four1}=#{four2}&#{five1}=#{five2}"
encoded_string = CGI.escape string
url = "https://api.twitter.com/oauth/request_token"
encoded_url = CGI.escape url
encoded_string = "POST&" + encoded_url + "&" + encoded_string
signing_key = 'xJPBJ2OdV6nM8r9e6ZysbnHTrZYm4R7LaY9OafNNNY3BkT4Oym'
encoded_signing_key = signing_key + '&'
digest = OpenSSL::Digest.new( 'sha1' )
hmac = OpenSSL::HMAC.digest( digest, encoded_signing_key, encoded_string)
signature = Base64.encode64( hmac ).chomp.gsub( /\n/, '' )

uri = URI.parse("https://api.twitter.com/oauth/request_token")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/x-www-form-urlencoded"
oauth = 'OAuth ' + one1 + '="' + oauth_consumer_key + '", ' + two1 + '="' + oauth_nonce + '", ' + CGI::escape('oauth_signature') + '="' + (CGI.escape signature) + '", ' + three1 + '="HMAC-SHA1", ' + four1 + '="' + oauth_timestamp.to_s  + '", ' + five1 + '="1.0"'
puts oauth
request['Authorization'] = oauth
request.body = ""
req_options = {
    use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
    http.request(request)
end
puts response
puts response.body

我还想为您提供一种更好地处理参数的方法,以生成基本字符串和标题:

require 'net/http'
require 'uri'
require 'base64'
require 'cgi'
require 'openssl'
require 'securerandom'

oauth_consumer_key = '<KEY>'
oauth_consumer_secret = '<SECRET>'
oauth_consumer_secret += '&'
oauth_timestamp = Time.now.getutc.to_i.to_s
oauth_nonce = SecureRandom.hex(10) + oauth_timestamp
oauth_signature_method = "HMAC-SHA1"
oauth_version = "1.0"

url = "https://api.twitter.com/oauth/request_token"
uri = URI.parse(url)
params = {
  'oauth_consumer_key' => oauth_consumer_key,
  'oauth_nonce' => oauth_nonce,
  'oauth_signature_method' => oauth_signature_method,
  'oauth_timestamp' => oauth_timestamp.to_s,
  'oauth_version' => oauth_version
}

base_string = "POST&" + CGI::escape(url) + "&" + CGI::escape(params.sort.collect{ |k,v| "#{CGI::escape(k)}=#{CGI::escape(v)}" }.join('&'))
oauth_signature = Base64.encode64("#{OpenSSL::HMAC.digest('sha1', oauth_consumer_secret, base_string)}").chomp

params['oauth_signature'] = oauth_signature

uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

header = "OAuth " + params.sort.collect {|k,v| "#{CGI::escape(k)}=\"#{CGI::escape(v)}\""}.join(", ")
rsp, data = http.post(uri, nil, {'Authorization' => header })

puts rsp
puts rsp.body

另一个建议是使用现有的OAuthgem。当您使用这个著名的库时,您还可以从Twitter获得支持。

gem install oauth
require 'oauth'

oauth_consumer = OAuth::Consumer.new("<KEY>", "<SECRET>", :site => "https://api.twitter.com")

access_token = OAuth::AccessToken.new(oauth_consumer)

request_token = access_token.request(:post, "/oauth/request_token")
rsp = request_token.body
puts rsp
 类似资料:
  • 我询问了如何建立一个服务呼叫,并在HttpClient上获得了一个很好的信息。然而,虽然这个问题在技术上得到了回答,但我还是被卡住了。 在控制台中,我可以看到我的浏览器向服务发送了什么请求来获取授权令牌。然而,当我尝试在我的服务层中模拟构建请求的调用时,我得到以下错误消息。我在这里犯错的可能性很大。不知道该用谷歌搜索什么,真的。。。 "StatusCode: 500, ReasonPhrase:'

  • 我正在尝试在ec2的两个实例上设置zookeeper。如这里和这里所示。我正在尝试运行zookeeper,但失败了,出现了一个错误:命令:

  • 我无法登录我的系统。当我在我的web表单中插入数据并点击登录按钮时,我的系统不工作。(数据是正确的)。 用户实体: 用户存储库: 安全配置: 错误消息:

  • 我正在设置一个KeyVault来从我的. NET Azure WebApp中删除秘密,并通过CredScan,据我所知,一切都已正确连接。 KeyVault与应用程序存在于同一资源组中,并且具有所需的机密。应用程序服务在KeyVault的访问策略中设置了显式读取权限。所有正确的参数都用于在代码中创建API客户机,遵循文档。 然而,当我使用标准API调用使用客户端实际访问一个秘密时,即。 我得到以下

  • 我使用电话身份验证在react native应用程序中使用这个文档,我在一些不同的设备中测试了它。有时电话可以工作,但有时会抛出此错误 firebase phone身份验证错误:无效令牌。在nativeToJSError 我已经浏览了firebase的文档,并试图理解这个错误。下面是我的代码片段:

  • 首先,我的证书经过100次测试。 我的PHP代码: 我可以以匿名身份成功绑定,但当我添加用户和密码时,绑定失败。 LDAP调试: 错误代码为49/52F 但是我对这个用户没有任何限制。我已经成功地从控制台将自己连接到AD上。 我已经尝试了$dn=“cn=用户,dc=域,dc=本地”或其他组合,但没有成功