環境
MacOS 11.2.1
Ruby 3.0.0
Rails 6.1.0
devise 4.7.3
omniauth 1.9.1
omniauth-github 1.4.0
omniauth-oauth2 1.7.1
過程
deviseでユーザー認証機能を導入した後、下記のサイトにのっとってGitHub認証を導入する。
https://github.com/heartcombo/devise/wiki/OmniAuth:-Overview
問題
概ねの実装を行ったがAPIにPOSTしている時点でコケてしまう。
結論
以下2パターンの間違いがほぼ同じエラーを出していた。エラーが似ているので、片方が間違えたまま、もう片方を修正しても動作確認でわからない。
- OAuth AppsとGitHub Appsを間違える(詳細は下記)
- token_params: { parse: :json }をDeviseのconfigに設定する(詳細は下記)
解決方法
本当はログをよくチェックするべきだったと思います。
自分の場合は、POSTのあと”Invalid Credential”と出ているので、Deviseの設定が怪しいと思って一つ一つ直しながらひたすら動作確認をしていました。
OAuth AppsとGitHub Appsを間違える、とは
developer settingsによく似た二つの項目がある。
GitHub AppsとOAuth Apps
OmniAuthでGitHub認証で必要なのはOAuthAppsで生成するIDとSECRET。
まちがえてGitHubAppsで生成するIDとSECRETを使うと以下のような現象が起こる。
1度目のみ認証画面になる
認証してもログインできず、2度目以降は認証画面は出ず、ログインに失敗しつづける
ログ
1回目
48826 Started POST "/users/auth/github" for ::1 at 2021-03-05 10:17:35 +0900
48827 Started GET "/users/auth/github/callback?code=xxx&state=xxx" for ::1 at 2021-03-05 10:20:24 +0900
48828 Processing by Users::OmniauthCallbacksController#failure as HTML
48829 Parameters: {"code"=>"xxx", "state"=>"xxx"}
48830 Redirected to http://localhost:3000/
48831 Completed 302 Found in 3ms (ActiveRecord: 0.0ms | Allocations: 334)
2回目以降
48876 Started POST "/users/auth/github" for ::1 at 2021-03-05 10:30:39 +0900
48877 Started GET "/users/auth/github/callback?code=xxx&state=xxx" for ::1 at 2021-03-05 10:30:39 +0900
48878 Processing by Users::OmniauthCallbacksController#failure as HTML
48879 Parameters: {"code"=>"xxx", "state"=>"xxx"}
48880 Redirected to http://localhost:3000/
48881 Completed 302 Found in 1ms (ActiveRecord: 0.0ms | Allocations: 205)
コンソール
Started POST "/users/auth/github" for ::1 at 2021-03-05 10:30:39 +0900
I, [2021-03-05T10:30:39.445975 #78131] INFO -- omniauth: (github) Request phase initiated.
Started GET "/users/auth/github/callback?code=xxx&state=xxx" for ::1 at 2021-03-05 10:30:39 +0900
I, [2021-03-05T10:30:39.860370 #78131] INFO -- omniauth: (github) Callback phase initiated.
E, [2021-03-05T10:30:40.842629 #78131] ERROR -- omniauth: (github) Authentication failure! invalid_credentials: OAuth2::Error, :
{"message":"Resource not accessible by integration","documentation_url":"https://docs.github.com/rest/reference/users#list-email-addresses-for-the-authenticated-user"}
Processing by Users::OmniauthCallbacksController#failure as HTML
Parameters: {"code"=>”xxx”, "state"=>”xxx”}
Redirected to http://localhost:3000/
Completed 302 Found in 1ms (ActiveRecord: 0.0ms | Allocations: 205)
コンソールの方のログを見るとAuthentication failure! invalid_credentials
となっている
token_params: { parse: :json }をDeviseのconfigに設定する、とは
Facebook認証をする場合、あるバージョン以降、レスポンスフォーマットがJSONに変わっているので、それをパースする処理を加える必要があるそうな。
https://qiita.com/anoworl/items/ea04d941d5d2bdea0e66
config/initializers/devise.rb
config.omniauth :github, ENV["GITHUB_ID"], ENV["GITHUB_SECRET"], token_params: { parse: :json }
token_params: { parse: :json }
の部分を加えるとJSONをパースしてくれる
GitHub認証には必要ない設定で、入れるとエラーになってしまう。
入れた場合、POST直後に認証失敗してログインできない。
エラーログ
49561 Started POST "/users/auth/github" for ::1 at 2021-03-05 10:46:03 +0900
49562 Started GET "/users/auth/github/callback?code=xxx&state=xxx" for ::1 at 2021-03-05 10:46:04 +0900
49563 Processing by Users::OmniauthCallbacksController#failure as HTML
49564 Parameters: {"code"=>"xxx", "state"=>"xxx"}
49565 Redirected to http://localhost:3000/
49566 Completed 302 Found in 1ms (ActiveRecord: 0.0ms | Allocations: 207)
コンソール
Started POST "/users/auth/github" for ::1 at 2021-03-05 10:46:03 +0900
I, [2021-03-05T10:46:03.756773 #78764] INFO -- omniauth: (github) Request phase initiated.
Started GET "/users/auth/github/callback?code=xxx&state=xxx" for ::1 at 2021-03-05 10:46:04 +0900
I, [2021-03-05T10:46:04.210471 #78764] INFO -- omniauth: (github) Callback phase initiated.
E, [2021-03-05T10:46:04.593857 #78764] ERROR -- omniauth: (github) Authentication failure! invalid_credentials: OAuth2::Error, access_token=xxx&scope=user%3Aemail&token_type=bearer
Processing by Users::OmniauthCallbacksController#failure as HTML
Parameters: {"code"=>"xxx", "state"=>"xxx"}
Redirected to http://localhost:3000/
Completed 302 Found in 1ms (ActiveRecord: 0.0ms | Allocations: 207)
コンソールの方のログを見るとAuthentication failure! invalid_credentials
となっている
二つの現象で非常によく似たエラーが出るので原因追求が難しかった。
しかしよくみると、GitHub APPに取り違えた方のエラーメッセージには{"message":"Resource not accessible by integration","documentation_url":"https://docs.github.com/rest/reference/users#list-email-addresses-for-the-authenticated-user”}
という情報が書いてある。この部分に気づければもっと早く解決していたかもしれない。
ちなみに単純にパスワードを間違えると
以下のログでPOSTしたまま以下の画面になるので動作確認ですぐに気づける
48807 Started POST "/users/auth/github" for ::1 at 2021-03-05 09:48:08 +0900