DeviseTokenAuth 控制器的强参数覆盖

Posted

技术标签:

【中文标题】DeviseTokenAuth 控制器的强参数覆盖【英文标题】:Strong parameter override for DeviseTokenAuth controller 【发布时间】:2016-02-02 23:44:26 【问题描述】:

我在 Rails 4.2 上使用 devise-token-auth gem,并在 User 模型中添加了一个字段 nickname。我正在尝试通过覆盖 gem 控制器来实现这一点

class Users::RegistrationsController < DeviseTokenAuth::RegistrationsController

  before_filter :configure_permitted_parameters

  def update
    #this line never shows in the logs
    Rails.logger.info "I never get to run!!"
    super
  end

  protected

  # my new custom field is :nickname
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) do |u|
      u.permit(:name, :nickname,
        :email, :password, :password_confirmation)
    end
    devise_parameter_sanitizer.for(:account_update) do |u|
      u.permit(:name,
        :email, :password, :password_confirmation, :nickname)
    end
  end
end

路由配置如下:

  Rails.application.routes.draw do
    namespace :api, constraints:  format: 'json'  do
        mount_devise_token_auth_for 'User', at: 'auth', controllers: 
          registrations:  'users/registrations'
        
    end
  end

他们似乎是对的:

PATCH  /api/auth(.:format)                    users/registrations#update :format=>"json"
PUT    /api/auth(.:format)                    users/registrations#update :format=>"json"

然后我尝试从curl调用更新

curl -X PUT --dump-header headers_update -H "Access-Token: 2FHhLQFtIgDfSqsTaaCH_g" -H "Uid: sample5@example.com" -H "Client: -RUtwnCfgqvqwDjYPtajQA" -H "Token-Type: Bearer" -H "Expiry: 1447713314" http://api.local.dev:3000/api/auth -d " \"nickname\":\"somestuff\""

但是更新调用永远不会运行。这是请求后显示服务器的内容:

I, [2015-11-02T18:05:38.131091 #7940]  INFO -- : Started PUT "/api/auth" for 127.0.0.1 at 2015-11-02 18:05:38 -0500
I, [2015-11-02T18:05:38.131222 #7940]  INFO -- : Started PUT "/api/auth" for 127.0.0.1 at 2015-11-02 18:05:38 -0500
I, [2015-11-02T18:05:38.147209 #7940]  INFO -- : Processing by Users::RegistrationsController#update as */*
I, [2015-11-02T18:05:38.147383 #7940]  INFO -- : Processing by Users::RegistrationsController#update as */*
I, [2015-11-02T18:05:38.147490 #7940]  INFO -- :   Parameters: " \"nickname\":\"somestuff\""=>nil
I, [2015-11-02T18:05:38.147571 #7940]  INFO -- :   Parameters: " \"nickname\":\"somestuff\""=>nil
D, [2015-11-02T18:05:38.152778 #7940] DEBUG -- :   User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."uid" = $1 LIMIT 1  [["uid", "sample5@example.com"]]
D, [2015-11-02T18:05:38.152934 #7940] DEBUG -- :   User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."uid" = $1 LIMIT 1  [["uid", "sample5@example.com"]]
D, [2015-11-02T18:05:38.224790 #7940] DEBUG -- : Unpermitted parameter:  "nickname":"somestuff"
D, [2015-11-02T18:05:38.225023 #7940] DEBUG -- : Unpermitted parameter:  "nickname":"somestuff"
I, [2015-11-02T18:05:38.237415 #7940]  INFO -- : Filter chain halted as :validate_account_update_params rendered or redirected
I, [2015-11-02T18:05:38.237565 #7940]  INFO -- : Filter chain halted as :validate_account_update_params rendered or redirected
I, [2015-11-02T18:05:38.237741 #7940]  INFO -- : Completed 422 Unprocessable Entity in 90ms (Views: 0.3ms | ActiveRecord: 0.7ms)
I, [2015-11-02T18:05:38.237860 #7940]  INFO -- : Completed 422 Unprocessable Entity in 90ms (Views: 0.3ms | ActiveRecord: 0.7ms)

curl的json回复是:

"status":"error","errors":["Please submit proper account update data in request"]

供参考,这是我的Gemfile

source 'https://rubygems.org'


gem 'rails', '4.2.1'

gem 'rails-api'

gem 'pg'
gem 'activerecord-postgis-adapter'
gem 'rgeo'
gem 'devise'
gem 'devise_token_auth', ">= 0.1.32.beta9" # Token based authentication for Rails JSON APIs
gem 'omniauth' # required for devise_token_auth

group :development, :test do
    gem 'pry-byebug', '=1.3.3'
    gem 'pry-stack_explorer'
    gem 'pry-rails'
    gem 'pry-remote'

  # Access an IRB console on exception pages or by using <%= console %> in views
  gem 'web-console', '~> 2.0'

  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'

  gem "rspec-rails", "~> 3.3"
end

group :test do

  #gem "shoulda-matchers"
  gem "factory_girl_rails"
  gem 'ffaker'
end

【问题讨论】:

【参考方案1】:

它对我有用。

    devise-token-auth gem 中提取RegistrationsController 创建app/controllers/users/registrations_controller.rb:

.

class Users::RegistrationsController < DeviseTokenAuth::RegistrationsController

end

并粘贴 p.1 中的内容

    添加到控制器的末尾:

.

def sign_up_params              
   params.require(:registration).permit(:name, :nick, :email, :password, :password_confirmation)

end
    像你一样配置路由

更新:

对第 3 步的更改适用于 devise_token_auth v0.1.39: def sign_up_params permit(:name, :email, :password, :password_confirmation) end

【讨论】:

【参考方案2】:

您可以通过这样做覆盖设计注册控制器:

class RegistrationsController < Devise::RegistrationsController

  private

  def sign_up_params
    params.require(:user).permit(:name, :nickname, :email, :password, :password_confirmation)
  end

  def account_update_params
    params.require(:user).permit(:name, :nickname, :email, :password, :password_confirmation, :current_password)
  end
end

然后在你的路线上:

devise_for :users, :controllers =>  registrations: 'registrations' 

【讨论】:

以上是关于DeviseTokenAuth 控制器的强参数覆盖的主要内容,如果未能解决你的问题,请参考以下文章

UITextField 上的强密码覆盖

NB-IOT覆盖范围有多大 NB-IOT的强覆盖是怎么实现的

TypeScript 中的强类型剩余参数

禁用特定操作的强参数

ASP.NET MVC - 用不同的参数覆盖一个动作

无法解析 symfony 4.3 中覆盖 FOS 控制器的参数 $token