Torihaji's Growth Diary

Little by little, no hurry.

Rails7でdevise-token-authを使って登録するまでの奮闘記-2章

はじめに

みなさん、こんにちは torihaziです。

前章では、無事確認メールを飛ばすとこまでいけました。

時刻は14時30分。

何時までに終わるのでしょうか。

現状

対象のapicurlでPOSTリクエストを飛ばし、

200のレスポンスが帰ってきて、

メールも来て、Railsのコンソールを見てもDBに登録されていることを確認。

ただ、ここからどうするのっていう状態。

DBのログ見たらなんか出てるし。

Unpermitted parameters: :config, :redirect_url. Context: { controller: DeviseTokenAuth::ConfirmationsController, action: show, request: #<ActionDispatch::Request:0x0000ffff92f7a7a0>, params: {"config"=>"default", "confirmation_token"=>"[FILTERED]", "redirect_url"=>"http://localhost:3001", "controller"=>"devise_token_auth/confirmations", "action"=>"show"} }

というかそもそも登録した時になんか出てる。

Parameters: {"name"=>"hoge2", "email"=>"hoge2@mail.com", "password"=>"[FILTERED]", "tel"=>"09083838383", "birth"=>"2024-04-04", "registration"=>{"name"=>"hoge2", "email"=>"hoge2@mail.com", "password"=>"[FILTERED]", "tel"=>"09083838383", "birth"=>"2024-04-04"}}

追加した覚えのない registrationとかいう項目が増えてる。

Unpermitted parameters: :confirm_success_url, :registration.

こんなん言われてるし。

なんか違うのかな。

でもconfirm_success_urlなんて許可してないよって出るのは

そりゃApplicationController.rbに書いてるストロングパラメータで

指定してないからそらそうだわな。

# frozen_string_literal: true

class ApplicationController < ActionController::API
  before_action :configure_permitted_parameters, if: :devise_controller?
  include DeviseTokenAuth::Concerns::SetUserByToken

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :tel, :birth])
  end
end

でも逆にここでconfirm_success_urlって追記すると逆に422で

跳ねられちゃうんだよね。

この方法ダメなのかね。

方針転換しよう。

コントローラ作って、そこに書くことにしよう。

qiita.com

ということでコントローラとルーティング変更。

前章からコントローラとかauth/registrationsが

users/registrationsに変わってます。(auth => users)

routes.rb

Rails.application.routes.draw do

  mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
  
  namespace :api do
    namespace :v1 do
      mount_devise_token_auth_for 'User', at: 'users', controllers: {
        registrations: "users/registrations"
      }
    end
  end
end

api/v1/users/registrations_controller.rb

class Api::V1::Users::RegistrationsController < DeviseTokenAuth::RegistrationsController

  private

  def sign_up_params
    params.permit(:name, :email, :password, :tel, :birth, :confirm_success_url)
  end

end

これで試してみよう。

curl localhost:3001/api/v1/users -i -X POST -d '{"name": "hoge1", "tel": "09012345648", "birth": "2024-04-04","email":"test1@example.com", "password":"password", "confirm_success_url": "http://localhost:3001"}' -H "content-type:application/json"

routing errorで返されました。なぜ。

こう書かないといけないみたい。

  namespace :api do
    namespace :v1 do
      mount_devise_token_auth_for 'User', at: 'users', controllers: {
        registrations: "api/v1/users/registrations"
      }
    end
  end

もう一回。

だめだ。

あとあれだ。

Parameters: {"name"=>"hoge2", "email"=>"hoge2@mail.com", "password"=>"[FILTERED]", "tel"=>"09083838383", "birth"=>"2024-04-04", "registration"=>{"name"=>"hoge2", "email"=>"hoge2@mail.com", "password"=>"[FILTERED]", "tel"=>"09083838383", "birth"=>"2024-04-04"}}

追加した覚えのない registrationとかいう項目が増えてる。

これ、registration は device-token-authが勝手に生成するみたい。

なので正しい手法として次のように修正

コントローラ

class Api::V1::Users::RegistrationsController < DeviseTokenAuth::RegistrationsController
  private

  def sign_up_params
    params.require(:registration).permit(:name, :email, :password, :tel, :birth, :confirm_success_url)
  end
end

curlコマンド例

curl localhost:3001/api/v1/users -i -X POST -d '{"registration": {"name": "hoge1", "tel": "09012345648", "birth": "2024-04-04", "email":"test1@example.com", "password":"password", "confirm_success_url": "http://localhost:3001"}}' -H "content-type:application/json"

こんなふうにcurlを投げるとDBには

Processing by Api::V1::Users::RegistrationsController#create as / Parameters: {"registration"=>{"name"=>"hoge1", "tel"=>"09012345648", "birth"=>"2024-04-04", "email"=>"test1@example.com", "password"=>"[FILTERED]", "confirm_success_url"=>"http://localhost:3001"}}

と重複されない。らしい。そんなの書いてあったか?まいいや。

というかこれが正しいなら

今、巷で出てる記事、花丸ではなく三角では?

兎にも角にも、結局

ActiveModel::UnknownAttributeError (unknown attribute 'confirm_success_url' for User.):

と怒られたので、コントローラ側の記載を消して再ポスト。

でもそしたらconfirm_success_urlとってこれなくないか

"errors":["Missing 'confirm_success_url' parameter."],

ほら。でしょうね。

え。詰みじゃね。

なんでーーーーーーーーーーーーーーーーーーーーー。

もう一回本家みてみる。

Email registration. Requires email, password, password_confirmation, and confirm_success_url params (this last one can be omitted if you have set config.default_confirm_success_url

このconfirmなんとかurlはconfirmableにしたから絶対いる。

けど、これをpostリクエストのパラメータにしたら

ストロングパラメータすり抜けるからダメ。

てことはこれdefaultで設定しとけばいいんじゃね。

そしたらストロングパラメータ入れなくて済むし、

やってみよう。

これでダメなら髪切ってこよう。

devise_token_auth.rbに下記を追加。

DeviseTokenAuth.setup do |config|
~~~
  config.default_confirm_success_url = "http://localhost:3001"
end

書き方はこんな感じでいけるでしょ。

configいじったので再起動。

ということで現状整理

api/v1/users/registrations_controller.rb

class Api::V1::Users::RegistrationsController < DeviseTokenAuth::RegistrationsController
  private

  def sign_up_params
    params.require(:registration).permit(:name, :email, :password, :tel, :birth)
  end
end

routes.rb

# frozen_string_literal: true

Rails.application.routes.draw do

  mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
  
  namespace :api do
    namespace :v1 do
      mount_devise_token_auth_for 'User', at: 'users', controllers: {
        registrations: "api/v1/users/registrations"
      }
    end
  end
end

curl

curl localhost:3001/api/v1/users -i -X POST -d '{"registration": {"name": "hoge1", "tel": "09012345648", "birth": "2024-04-04", "email":"test1@example.com", "password":"password"}}' -H "content-type:application/json" 

せっかくだし、dbリセットするか。

では。失敗したら坊主で。

うまくはいった。

ただ、やっぱりdbのログには

unpermitted parameter 出るっぽい。

Parameters: {"registration"=>{"name"=>"hoge1", "tel"=>"09012345648", "birth"=>"2024-04-04", "email"=>"test1@example.com", "password"=>"[FILTERED]", "confirm_success_url"=>"http://localhost:3001"}}

Unpermitted parameter: :confirm_success_url. Context: { controller: Api::V1::Users::RegistrationsController, action: create, request: #<ActionDispatch::Request:0x0000ffff9bc144e0>, params: {"registration"=>{"name"=>"hoge1", "tel"=>"09012345648", "birth"=>"2024-04-04", "email"=>"test1@example.com", "password"=>"[FILTERED]", "confirm_success_url"=>"http://localhost:3001"}, "controller"=>"api/v1/users/registrations", "action"=>"create"} }

じゃそういうものとして理解する。

POSTリクエストには付与しなくても勝手に付与してくれるっぽい。

へー。

結局、さっきと変わってないじゃん。結論。

なんやねん。登録はできたけど、あとは確認の時か

終わりに

結局登録はできていたけど、

confirmなんとかのログは変わらないということが

1日を通して分かった。

..........

はい、次章に続きます。

今、16時30分です。2時間かかってよ。あー。