【Ruby on Rails】OmniAuthのGitHub認証、APIにPOST時点でのエラー

### 環境
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している時点でコケてしまう。

### 結論
以下２パターンの間違いがほぼ同じエラーを出していた。エラーが似ているので、片方が間違えたまま、もう片方を修正しても動作確認でわからない。
- OAuth AppsとGitHub Appsを間違える（詳細は下記）
- token_params: { parse: :json }をDeviseのconfigに設定する（詳細は下記）


### 解決方法
本当はログをよくチェックするべきだったと思います。
自分の場合は、POSTのあと”Invalid Credential”と出ているので、Deviseの設定が怪しいと思って一つ一つ直しながらひたすら動作確認をしていました。

#### OAuth AppsとGitHub Appsを間違える、とは
developer settingsによく似た二つの項目がある。
GitHub AppsとOAuth Apps

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161567/e00585fc-207d-3434-1790-be4de9618e34.png)
￼
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161567/37a4980a-d8b0-4215-76d5-6126037f0495.png)
￼￼


OmniAuthでGitHub認証で必要なのはOAuthAppsで生成するIDとSECRET。
まちがえてGitHubAppsで生成するIDとSECRETを使うと以下のような現象が起こる。

1度目のみ認証画面になる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161567/21801bad-b276-5974-c265-36a3786442f3.png)
￼

認証してもログインできず、2度目以降は認証画面は出ず、ログインに失敗しつづける

ログ
１回目

```ruby
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)
```
２回目以降

```ruby
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)
```

コンソール

```ruby
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``

```ruby
config.omniauth :github, ENV["GITHUB_ID"], ENV["GITHUB_SECRET"], token_params: { parse: :json }
```
``token_params: { parse: :json }``の部分を加えるとJSONをパースしてくれる

GitHub認証には必要ない設定で、入れるとエラーになってしまう。

入れた場合、POST直後に認証失敗してログインできない。

エラーログ

```ruby
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)
```

コンソール

```ruby
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したまま以下の画面になるので動作確認ですぐに気づける

```ruby
48807 Started POST "/users/auth/github" for ::1 at 2021-03-05 09:48:08 +0900
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161567/3f49d58c-d6d1-443e-7d86-c426fc9e9834.png)