获取意外的用户参数并且无法访问Rails中的密码参数

我开始在Rails with React中设置用户身份validation系统,并且发生了两件奇怪的事情:

1)我的POST请求包括一个user参数,我很确定我没有自己配置(我跟着一本Rails指南书)。 此user参数包含所有其他参数的重复,如下所示:

 Started POST "/api/user" for 127.0.0.1 at 2018-01-29 21:54:42 -0800 Processing by Api::UserController#create as JSON Parameters: {"email"=>"test@test.com", "password"=>"[FILTERED]", "first_name"=>"test", "last_name"=>"test", "groupname"=>"test", "admin"=>"true", "user"=>{"email"=>"test@test.com", "first_name"=>"test", "last_name"=>"test", "groupname"=>"test", "admin"=>"true"}} Can't verify CSRF token authenticity. No template found for Api::UserController#create, rendering head :no_content Completed 204 No Content in 39ms (ActiveRecord: 0.0ms) 

2)如果您没有注意到,我的password参数是唯一一个未包含在我的user参数中的password (可能是因为我在我的users模型中调用了has_secure_password ?),我无法弄清楚如何添加它到我的private变量。

我只是尝试使用Users.new()将我的新用户信息写入我的Postgres数据库。 这是我正在使用的:

index.js

 class Signup extends React.Component { constructor(props) { super(props) this. state = { email: '', password: '', first_name: '', last_name: '', groupname: '', admin: false } this.handleChange = this.handleChange.bind(this) this.handleSubmit = this.handleSubmit.bind(this) } handleChange(e) { const { name, value } = e.target this.setState({ [name]: value }) } handleSubmit(e) { e.preventDefault() axios.post('/api/user', { email: this.state.email, password: this.state.password, first_name: this.state.first_name, last_name: this.state.last_name, groupname: this.state.groupname, admin: this.state.admin }) .then(res => { console.log(res.data) }) } render() { return ( 

Sign Up!

Create Account



Already a Member?
) }

index.html.erb

  

应用程序/控制器/ API / user_controller.rb

 class Api::UserController < ApplicationController respond_to :json protect_from_forgery with: :null_session def create user_params[:password] = params[:password] puts user_params @user = Users.new(user_params) end private def user_params params.require(:user).permit(:email, :password, :first_name, :last_name, :groupname, :admin) end end 

应用程序/模型/ user.rb

 class User < ApplicationRecord before_save { self.email = email.downcase } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[az\d\-.]+\.[az]+\z/i validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } validates :first_name, presence: true, length: { maximum: 51 } validates :groupname, presence: true, length: { maximum: 51 } validates :password, presence: true, length: { minimum: 6 } has_secure_password end 

数据库架构

  create_table "users", force: :cascade do |t| t.string "email" t.string "password_digest" t.string "first_name" t.string "last_name" t.integer "groupid" t.string "groupname" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.boolean "admin" t.index ["email"], name: "index_users_on_email", unique: true end 

总而言之,我的实际问题是:为什么我得到一个单独的users参数,为什么它不包含我的密码,为什么我不能将密码添加到我的user_params

Rails有一个配置选项wrap_parameters ,默认情况下启用。 这将检测您是否未提供根元素(在此实例中为:user ),并将密钥复制到根元素中。 这就是造成你第一个问题的原因。

密码不包含在包装参数中,因为它不是模型上的已定义属性。 仅包装类方法attribute_names中返回的键。 您可以在控制器中使用以下方法明确包含其他键:

 class UsersController < ApplicationController wrap_parameters :user, include: [:password] end 

或者,您可以将您发送到rails控制器的参数嵌套在user密钥下,并完全忽略wrap_parameters

 axios.post('/api/user', { user: { email: this.state.email, password: this.state.password, first_name: this.state.first_name, last_name: this.state.last_name, groupname: this.state.groupname, admin: this.state.admin } })