lynndylanhurley / devise_token_auth

Token based authentication for Rails JSON APIs. Designed to work with jToker and ng-token-auth.
Do What The F*ck You Want To Public License
3.55k stars 1.14k forks source link

Default URL params confirmation_instructions.html.erb conflicts with ones permitted in DeviseTokenAuth::ConfirmationsController #1558

Open BirkhoffLee opened 2 years ago

BirkhoffLee commented 2 years ago

The Issue

I'm new to Ruby and Rails, trying to build a RESTful API with Rails 7 API mode. Our team is trying to integrate this gem and when developing the email confirmation feature I found Rails keep complaining about

Started GET "/api/v1/recruitment/auth/applicant/confirmation?config=default&confirmation_token=[FILTERED]&redirect_url=%2F" for 127.0.0.1 at 2022-10-06 21:20:05 +0800
Processing by DeviseTokenAuth::ConfirmationsController#show as */*
  Parameters: {"config"=>"default", "confirmation_token"=>"[FILTERED]", "redirect_url"=>"/"}
Unpermitted parameters: :config, :redirect_url. Context: { controller: DeviseTokenAuth::ConfirmationsController, action: show, request: #<ActionDispatch::Request:0x000000010b3b3420>, params: {"config"=>"default", "confirmation_token"=>"[FILTERED]", "redirect_url"=>"/", "controller"=>"devise_token_auth/confirmations", "action"=>"show"} }
  RApplicant Load (0.1ms)  SELECT "r_applicants".* FROM "r_applicants" WHERE "r_applicants"."confirmation_token" = ? ORDER BY "r_applicants"."id" ASC LIMIT ?  [["confirmation_token", "[FILTERED]"], ["LIMIT", 1]]
Completed 404 Not Found in 15ms (ActiveRecord: 0.9ms | Allocations: 8631)

ActionController::RoutingError (Not Found):

In particular, take a look on this:

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

What I have tried

After hours of research I found some evidence indicating that this is a devise_token_auth bug, yet I had to do some more research on Strong Parameters, and I learned that somewhere in the ConfirmationsController there are those "Strong Parameters Settings", which is in app/controllers/devise_token_auth/confirmations_controller.rb#L74:

...
    private

    def resource_params
      params.permit(:email, :confirmation_token, :config_name)
    end
...

These params do not match the ones in the default email template:

<p><%= link_to t('.confirm_account_link'), confirmation_url(@resource, {confirmation_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url']}).html_safe %></p>

This is obviously why Rails did not complain about confirmation_token - because it's the only param overlapping in both places.

Mitigations

Right now before there is a fix, a temporal fix is to override resource_params method in DeviseTokenAuth::ConfirmationsController:

class Auth::ConfirmationsController < DeviseTokenAuth::ConfirmationsController
  private
    def resource_params
      params.permit(:email, :confirmation_token, :config_name, :redirect_url)
    end
end

and use this controller with:

mount_devise_token_auth_for 'RApplicant', at: 'api/v1/recruitment/auth/applicant', controllers: {
  confirmations: 'auth/confirmations'
}

Potential fix

Have the strong params in confirmations_controller.rb match with the ones in confirmation_instructions.html.erb.