gpt4 book ai didi

ruby - 尝试使用Oauth 1.0获取Twitter request_token的过程中,始终出现 '215 Bad Authentication'错误

转载 作者:行者123 更新时间:2023-12-03 16:17:46 34 4
gpt4 key购买 nike

我正在尝试从Twitter获取Oauth请求 token -我正在遵循他们的指南(下面的链接),并且每步都经过了大约10次,但我无法弄清楚为什么会出现此错误:

{\"errors\":[{\"code\":32,\"message\":\"Could not authenticate you.\"}]}



他们使用Oauth 1.0。我应该在请求中组合所有百分比编码的参数,对它们进行百分比编码,添加请求方法(POST)和请求url,使用该参数加上我的api key secret 来创建签名,并将签名添加到我的最终发布请求。签名文档在 this page上,后续的Post request文档在 this page上。我使用了指南中给出的示例代码来生成签名,并且得到了与指南相同的结果,因此我认为实际的签名生成没有问题。

我三重检查了我的api key 和api key secret 以及回调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

这是我的 request["Authorization"] header

"OAuth oauth_callback=\"http%3A%2F%2Fwww.example.localhost%3A3000%2Ftwittercallback\", oauth_nonce=\"e5686f142ca58a45af233fb66876671592457549dsd\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1592457549\", oauth_consumer_key=\"[KEY]\", oauth_signature=\"n9MNLO%2Ft%2FT6WX0Myu5JcTICXNAQ%3D\", oauth_version=\"1.0\""



这是Twitter的 docs的示例标题:

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"

最佳答案

您没有提供必需的Authorization header ,但为每个参数提供了单独的 header 。您需要将以下形式的参数组合为字符串,并且首先使用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"
并在 Authorization header 中提供该代码:
request['Authorization'] = <OAuth string>
您的代码中还有很多其他问题,为什么它不起作用:
  • 错误转义参数
  • 转义签名 key
  • dsd header
  • 中的 nonce中添加 Authorization
  • 授权 header 中的数据顺序错误(按字典顺序,例如,对于大多数按字母顺序排列的图书馆而言)

  • 因此,如果我们重新处理您的代码,则会导致以下结果:
    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
    我还想给您提供一种更好地处理参数的方法,以生成 base_stringheader:
    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
    另一个建议是使用现有的 OAuth gem。使用这个众所周知的库时,您还可以从 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

    关于ruby - 尝试使用Oauth 1.0获取Twitter request_token的过程中,始终出现 '215 Bad Authentication'错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62382188/

    34 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com