現象
最近作り始めた Rails のアプリケーションで OmniAuth OAuth2 を使おうとしたら、なぜか、ずっと Invalid Credentials: invalid_grant
のエラーになってしまっていました。
Doorkeeper で作った別の Rails アプリが OAuth2 のサーバだったのですが、前に作った Rails アプリからは問題ない……ほとんど同じ作り方のはずなのに。
調査
おかしいと思って調べたら、どうやら 1.4.0 に入り込んだ変更のためらしいです。
1.4.0 makes my rails app unable to sign in with facebook · Issue #81 · intridea/omniauth-oauth2
に書いてある このコメント によると、OAuth 2 のこの仕様 を実装したところ、いろんな OAuth2 のプロバイダが壊れてしまったようです。
つまり、自分で OAuth2 のプロバイダを書いているようなプロジェクトが被害を受けたようです(自分のプロジェクトもそうでした)。
対策
対策は大きく2つあります。
1. Gem のバージョンを下げる
1.3.1 に下げれば回避できます。
gem 'omniauth-oauth2', '~> 1.3.1'
2. callback_url
をオーバーライドする
軽く説明をすると、本来コールバックで URL を変更してはいけないところを、今までの OmniAuth プロバイダはそれをしてしまっており、1.4.0 の変更がそれをチェックしてしまっていることがことの原因です。
なので、プロバイダの Strategy
側も callback_url を仕様通り、変更しないまま返せばいいわけのようです。
module OmniAuth
module Strategies
class YourOAuth2Strategy < OmniAuth::Strategies::OAuth2
:
def callback_url
full_host + script_name + callback_path
end
参考: fix broken backward compatibility (callback_url) by zmajstor · Pull Request #82 · intridea/omniauth-oauth2
残念(?)ながら、こちらのプルリクエストは取り込まれませんでした。
個人的には、いずれ gem のバージョンを上げるときが来る点と仕様に沿っている点から、後者を選ぶべきかとは思います。