【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
でログインできました。