devise_token_auth + omniauthにログアウトを追加

前回の[devise_token_authとomniauthを使ったログインを試す](https://qiita.com/AQeNku/items/94485432184257799106)からの続き。
最初は古いclient_idやtokenをログイン時に再発行されたやつで上書きしていると思っていたけど、どうやら上書きしないでひたすら追加するだけっぽい。
そのためusersテーブルを確認したら使われなくなったclient_idやtokenがtokensカラムにもりもり溜まっていた。
これはさすがによろしくないのでログアウトを追加して不要になったclient_idとtokenは消すことにする。

## 1. ルーティングの追加

現時点でのルーティング

```
$ rails routes
             Prefix Verb     URI Pattern                            Controller#Action
auth_validate_token GET      /auth/validate_token(.:format)         devise_token_auth/token_validations#validate_token
       auth_failure GET      /auth/failure(.:format)                users/omniauth_callbacks#omniauth_failure
                    GET      /auth/:provider/callback(.:format)     users/omniauth_callbacks#omniauth_success
                    GET|POST /omniauth/:provider/callback(.:format) users/omniauth_callbacks#redirect_callbacks
   omniauth_failure GET|POST /omniauth/failure(.:format)            users/omniauth_callbacks#omniauth_failure
                    GET      /auth/:provider(.:format)              redirect(301)
    application_api          /                                      ApplicationAPI
```

本当なら```/auth/sign_out```が良いんだろうけど```/omniauth/sign_out```にリダイレクトされてしまうので```/users/sign_out```として追加する。

```ruby:config/routes.rb
Rails.application.routes.draw do
  mount_devise_token_auth_for 'User', at: 'auth', controllers: {
    omniauth_callbacks: "users/omniauth_callbacks"
  }
  as :user do
     delete '/users/sign_out', to: 'users/sessions#destroy', as: :destroy_user_session
  end
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  mount ApplicationAPI, at: "/"
end
```
ルーティングの確認

```
rails routes
              Prefix Verb     URI Pattern                            Controller#Action
 auth_validate_token GET      /auth/validate_token(.:format)         devise_token_auth/token_validations#validate_token
        auth_failure GET      /auth/failure(.:format)                users/omniauth_callbacks#omniauth_failure
                     GET      /auth/:provider/callback(.:format)     users/omniauth_callbacks#omniauth_success
                     GET|POST /omniauth/:provider/callback(.:format) users/omniauth_callbacks#redirect_callbacks
    omniauth_failure GET|POST /omniauth/failure(.:format)            users/omniauth_callbacks#omniauth_failure
                     GET      /auth/:provider(.:format)              redirect(301)
destroy_user_session DELETE   /users/sign_out(.:format)              users/sessions#destroy
     application_api          /                                      ApplicationAPI
```


## 2. Sessionsコントローラの作成
ログアウト時に呼び出される```sessions_controller.rb```をdevise_token_authからコピーして```app/controllers/users```に設置して編集する。
以下は、変更箇所のみ抜粋。

```ruby:app/controllers/users/sessions_controller.rb
# module DeviseTokenAuth
module Users
  class SessionsController < DeviseTokenAuth::ApplicationController 
    def render_destroy_error
      render json: {
        message: I18n.t("devise_token_auth.sessions.user_not_found")
      }, status: 404
      # render_error(404, I18n.t("devise_token_auth.sessions.user_not_found"))
    end
  end
end
```
あとは使わないnewやcreate系はコメントアウトしておくといいかも。

## 3. 動作確認
サーバを起動した後、twitterなりfacebookなりでログインして有効なclient_idとtokenとuidを入手する。

その後curlなりPostmanなどで```http://localhost:3000/users/sign_out```にアクセスする。

```
$ curl -X DELETE -H 'client:XXXXXXXXXXXX' -H 'uid:XXXXXXXXXXXX' -H 'access-token:XXXXXXXXXXXXXX' http://localhost:3000/users/sign_out | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0    16    0    16    0     0     10      0 --:--:--  0:00:01 --:--:--    12
{
  "success": true
}
```

ログアウトに成功。
もう一度実行すると情報が見つからないというエラーメッセージが返ってくる。

```
$ curl -X DELETE -H 'client:XXXXXXXXXXXX' -H 'uid:XXXXXXXXXXXX' -H 'access-token:XXXXXXXXXXXXXX' http://localhost:3000/users/sign_out | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0    54    0    54    0     0     55      0 --:--:-- --:--:-- --:--:--    57
{
  "message": "User was not found or was not logged in."
}
```

これでログアウト処理が実装できた。