LoginSignup
10
7

More than 5 years have passed since last update.

Rubyでのgemを使わないtwitterのbarer_tokenの取得

Last updated at Posted at 2015-10-22

※タイトル変更しました。
(前タイトル:Rubyでのgemを使わないtwitterのoauth2用tokenの取得)

oauthの仕組みとrubyに慣れるため、twitterのoauth2用tokenの取得を自前で実装してみました。
検証は中途半端ですがメモがてら

ソースコード

  def twitter_auth
    api_key = '0Z2...........ANu'
    api_secret = 'EG50c.................................FYGvt'
    encoded_key =  URI.encode(api_key)
    encoded_secret =  URI.encode(api_secret)
    bearer_token = encoded_key + ":" + encoded_secret
    base64_token = Base64.strict_encode64(bearer_token)

    twitter_uri = URI.parse('https://api.twitter.com/oauth2/token')
    https = Net::HTTP.new(twitter_uri.host, twitter_uri.port)
    https.use_ssl = true
    https.verify_mode =  OpenSSL::SSL::VERIFY_NONE
    req = Net::HTTP::Post.new(twitter_uri)
    req["Authorization"] = "Basic #{base64_token}"
    req.content_type = 'application/x-www-form-urlencoded;charset=UTF-8' 
    https.set_debug_output $stderr
    res = https.request(req, body = 'grant_type=client_credentials')    
    render text: res.body
  end

はまった事

[事象]
https://api.twitter.com/oauth2/token の実行が上手く出来ない。
コーディングの過程で
リクエスト結果が
403エラー {"errors":[{"code":99,"message":"Unable to verify your credentials","label":"authenticity_token_error"}]}
400エラー が返ってくる。

[原因1]
リクエストヘッダ、Authorizationの値(Base64エンコーディングされてる)に\nが混ざっていた。

a)Base64エンコーディングの仕様の違いにより、リクエストヘッダの値が正しくデコードできない
当初利用していたrubyのBase64.encode(str)はRFC 2045に基づいており、1行あたりの文字数制限が存在するため、改行コードが入りうる。
一方でBase64.strict_encode64(str)はRFC 4648に基づいており、改行コードが入らない。
twitter側でのデコードの際、エンコーディングの違いにより、正しくデコードできなかった。

[原因2]
b)リクエストヘッダ内の改行コードが入ると、rubyのPOSTリクエストがおかしくなる?

・ruby
Authorizationの値に
\nが入った場合:ステータス400
誤った値の場合:ステータス403
正しい値の場合:ステータス200
が返ってくる。

・curl
Authorizationの値に
\nが入った場合:ステータス403
誤った値の場合:ステータス403
正しい値の場合:ステータス200
が返ってくる。

上記のように、rubyとcurlでは\nが入った場合のステータスが異なる。
どちらのPOSTリクエストが正しいかは不明ではあるが、
rubyの場合改行コードがリクエストヘッダに含まれると、意図しないリクエストが送出されるように思える。

この辺はhttpリクエストのキャプチャツールを使えば判りそうではあるが、今回は放置。

[混乱の元]
POSTリクエスト実装前の、Curlでの試験時、
p base64_token、ではなく
render text: base64_token で取得したtokenを利用したため、

bearer_tokenの値が
本来の、

MFo(省略)kZSQ2Zv\nT1RMS(省略)d2dA==

ではなく、

MFo(省略)kZSQ2Zv T1RMS(省略)d2dA==

(\nが半角スペースになっていたもの)を利用していた。

base64の値をデコードする際は、A–Z, a–z, 0–9 までの62文字と、記号2つ (+, /)、パディング記号(=)以外は無視されるみたいなので、半角スペースを含むtokenでは問題なくAPIを実行できていた様子。

10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7