【Rails】deviseで用意したログインAPIを叩いた際、見知らぬパラメータが渡っていた
RailsにてGem deviseで認証機能を実装した際、ログイン時のpostで謎のパラメータが渡る問題に直面。
その解決法をメモします。
謎のパラメータが渡る
ログインするためのAPIを叩いたところ、エラーがかえってきました。
Processing by DeviseTokenAuth::SessionsController#create as HTML
Parameters: {"email"=>"test1@example.com", "password"=>"[FILTERED]", "session"=>{"email"=>"test1@example.com", "password"=>"[FILTERED]"}}
Unpermitted parameter: :session
原因はUnpermitted parameter: :sessionにあると。
しかしAPIを叩く際にsessisonという名のパラメータは渡していません・・・。
Railsの仕様だった
こちらの記事に答えが書いてありました。 paramsとwrap_parameters
コントローラのparamsには、"user"というキーが自動的に付きます(値がラップされます)。これが、ActionController::ParamsWrapperの機能です。
ひえーなるほど。
つまり今回はSessionsControllerなので、sessionでラップされたパラメータも自動で用意されていたというわけです。
脱線しますがストロングパラメータを下記のように書けるのはこの機能のおかげだったのですね。
def user_params params.require(:user).permit(:name, :email) end
解決方法
独自のSessionsControllerを用意する
deviseのSessionsControllerを継承した独自のコントローラーを用意。
その際にwrap_parameters format: []を差し込むことで、パラメータにsessionが入らなくなります。
class Api::V1::Auth::SessionsController < DeviseTokenAuth::SessionsController wrap_parameters format: [] end
ルーティングの修正
先ほど作成したコントローラーが呼ばれるように、routes.rbを修正。
Rails.application.routes.draw do mount_devise_token_auth_for 'User', at: 'api/v1/auth', controllers: { registrations: 'api/v1/auth/registrations', sessions: 'api/v1/auth/sessions' #追加 } end
これでsessionというパラメータが入ることなく、emailとpasswordでログインできました。