環境
- docker-compose
- RailsAPI + devise-token-auth
- Next.js + React Hook Form
事象
ログインフォームを作っていたところ、この環境でフォームからRailsAPIにJSONをPOSTできないエラーが発生。
Railsのコンテナ側のログを見てみます。
えーなになに
Started POST "/v1/auth/" for 172.19.0.1 at 2022-02-01 20:42:18 +0900
Processing by V1::RegistrationsController#create as JSON
Parameters: {"name"=>"halkyo", "email"=>"hoge@hoge.hoge", "password"=>"[FILTERED]", "registration"=>{"name"=>"halkyo", "email"=>"hoge@hoge.hoge", "password"=>"[FILTERED]"}}
Unpermitted parameters: :format, :registration
えちょっとまって、JSONになんかくっついてる・・・
“registration”
・・・誰?
調べてみると、ReactHookFormからheadersを’Content-Type’: ‘application/json’とかでPOSTすると、必ず付いてくるみたい。(いらないんですけど??????)
このregistrationがストロングパラメータで引っかかっているみたい。
どうりでPostmanなんかではエラーが出なかったわけですね。(Postmanはrawでそのまま送ってくれる)
対処
原因の察しがつけばあとは書くのみ!!!
今回の対処法ですが、いっそregistrationのデータをRailsで受け取ってしまいます。
Rails側のcontrollerにストロングパラメータを追記しましょう。とはいえ、devise-token-authのコントローラーはapp/controllerには作られないので、新たにファイルを作成して、route.rbから指定します。
構成はapp/v1想定です
app/controller/v1/registrations_controller.rb
class V1::RegistrationsController < DeviseTokenAuth::RegistrationsController
private
def sign_up_params
params.require(:registration).permit(:name, :email, :password)
end
end
params.require(:registration).permit(:name, :email, :password)
config/route.rb
Rails.application.routes.draw do
namespace :v1, { format: 'json' } do
mount_devise_token_auth_for 'User', at: 'auth', controllers: {
registrations: "v1/registrations"
}
end
end
これでOK。registrationのデータを受け取ってくれるようになりました。
Railsコンテナ再起動で完了
Next.js側からPOSTしてみて動作確認して終了です。
人気jsフレームワークとはいえ、RailsAPIとの組み合わせはあまり情報がないですね。いい組み合わせだと思うんですけどね。
おわり🏆