カマカマの雑草ブログ

個人の日記です

SorceryでExternalが動かない際にはconfigのcallback_urlを見直してみる

Ruby on Rails初心者の断片プログラマーです(マサカリは程々にお願いしますの意)。
いま個人開発でRuby on Rails触っていて、認証部をシンプルな感じにして最高に楽をしたかったのでSorceryを利用しようとしたのですが、External(外部認証機能、OAuth認可するやつ)をTwitterで利用しようとした際にハマったのでここに解決法を記しておきます。

バージョン

結論

callback_urlのドメインは0.0.0.0だとsessionでrequest tokenを共有できなくてダメというやつです。
開発中はlocalhost, Productionならwww.yourawesomeservice.comとかである必要があります。
yourewasomeserviceは適宜よしなにお願いします。session共有できる設定とかでも多分平気(試してない)。

事象

Sorceryのチュートリアルの通りに進めていると、Twitterを介して認証処理が成功してcallbackした際に401 unauthorizedが返ってくるという問題があります。
他にも以下に挙げられているようなことが原因で発生することがあるみたいです。

Sorceryの実装

この辺
https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/providers/twitter.rb#L45-L53

:request_tokenと:request_token_secretをsessionから持ってきてるのが分かるかと思います。
get_access_tokenの実装はProtocols::Oauth下に
https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/protocols/oauth.rb#L22-L27

get_request_tokenではtokenとsecret見て、nilだったらTwitterに問い合わせる感じになってます。
https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/protocols/oauth.rb#L10-L13

これつまりどういうことかっていうと、初回のrequest_token取得時に利用したsessionと、その後のcallbackで利用するsessionが同一でないとrequest_tokenが適切に渡らず、request_tokenが適切に渡ってないとaccess_token取る前にもう一度request_tokenを発行しようとするわけです。
新しいrequest_tokenを発行しても実際に認証完了しているのは古い方のrequest_tokenなので、認証の済んでいない新しいrequest_tokenを使ってaccess_tokenを取ろうとしても401が返ってくるわけですね。

そして、特別な設定をしていない限りはRailsのsessionは異なるドメイン間で共有されないので、localhost内のsessionにrequest_tokenがあってもcallback実行時の0.0.0.0内のsessionにはrequest_tokenが入っていないという流れが起きます。

終わりに

こうして改めて見ると結構しょーもない理由で悩んでいた気がしますが、人が学びを重ねていく過程においては止むを得ないということで見なかったことにします。
何か誤りなどありましたら教えてください。謝ります。このジョーク超面白くないですか。