在Rails中获得意外的用户参数并且无法访问密码参数 [英] Getting Unexpected User Param and Can't access Password Param in Rails

查看:80
本文介绍了在Rails中获得意外的用户参数并且无法访问密码参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始使用React在Rails中设置用户身份验证系统,并且发生了两件事:

I started setting up a user authentication system in Rails with React and there are two weird things happening:

1)我的POST请求包含一个user参数,我敢肯定我没有配置自己(我正在跟着Rails指南书一起学习).此user参数具有我所有其他参数的重复项,如下所示:

1) My POST request is including a user param that I'm pretty sure I didn't configure myself (I was following along with a Rails guideline book). This user param has a duplication of all of my other params, as shown:

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参数中不包括的唯一参数(可能是因为我在users模型中调用了has_secure_password吗?) ,我不知道如何将其添加到我的private变量中.

2) If you didn't notice already, my password param is the only one that isn't included in my user param (probably because of me calling has_secure_password in my users model?), and I can't figure out how to add it to my private variable.

我只是试图使用Users.new()将新用户的信息写入到我的Postgres数据库中.这是我正在使用的东西:

I'm simply trying to write my new user's information into my Postgres database using Users.new(). Here is what I'm working with:

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 (
      <div>
        <h3>Sign Up!</h3>



        <section>
          <div>
                <div className='box'>
                  <p className="subtitle has-text-grey">Create Account</p>
                  <hr />

                  <form onSubmit={this.handleSubmit}>

                    <div className="field">
                      <div className="control">
                        <label>E-mail

                          <input name="email" type="text" className="form-control" onChange={this.handleChange} defaultValue={this.state.email}></input>

                        </label>
                      </div>
                    </div>


                    <div className="field">
                      <div className="control">
                        <label>Password

                          <input name="password" type="password" className="form-control" onChange={this.handleChange} defaultValue={this.state.password}></input>

                        </label>
                      </div>
                    </div>

                    <div className="field">
                      <div className="control">

                        <label >First Name

                          <input type="text" className="form-control" name="first_name" onChange={this.handleChange} defaultValue={this.state.first_name}></input>
                        </label>
                      </div>
                    </div>

                    <div className="field">
                      <div className="control">
                        <label>Last Name
                          <input type="text" className="form-control" name="last_name" onChange={this.handleChange} defaultValue={this.state.last_name}></input>
                        </label>
                      </div>
                    </div>

                    <div className="field">
                      <div className="control">
                        <label>Group


                          <input name="groupname" type="text" className="form-control" onChange={this.handleChange} defaultValue={this.state.groupname}></input>

                          <hr />

                          <span className='adminLabel' style={styles.adminLabelStyle}>Are you registerting as an admin?</span> <span>     </span>



                          <input type="checkbox" id="groupadmin" name="admin" onChange={this.handleChange} value='true'></input>

                        </label>
                      </div>
                    </div>

                    <div className="field is-grouped">
                      <div className="control">
                          <input type="submit" value='Submit' className="button is-normal is-info"></input>
                      </div>
                    </div>
                  </form>

                  <hr />

                  <form >
                    <div className="feild">
                      <div className="control">
                        <div>Already a Member?
                          <input type="submit" value='Login' className="" onClick={ this.props.action }></input>
                        </div>
                      </div>
                    </div>
                  </form>
            </div>
          </div>

        </section>


      </div>
    )
  }

index.html.erb

<%= react_component('Index') %>

app/controllers/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

app/models/user.rb

class User < ApplicationRecord
    before_save { self.email = email.downcase }
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\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 ??

All in all my actual questions are: WHY am I getting a separate users param, WHY doesn't it include my password, and WHY can't I add the password to my user_params??

推荐答案

Rails具有配置选项wrap_parameters,该选项默认情况下处于启用状态.这将检测您是否未提供根元素(在本例中为:user),并将为您复制密钥到根元素中.这就是导致您的第一个问题的原因.

Rails has a config option wrap_parameters which is enabled by default. This will detect if you haven't provided a root element (:user in this instance), and will duplicate the keys into a root element for you. That is what is causing your first issue.

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

Password isn't included in the wrapped parameters because it isn't a defined attribute on your model. Only the keys returned in the class method attribute_names are wrapped. You can get explicitly include additional keys with the following method in your controller:

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

或者,您可以仅将要发送到rails控制器的参数嵌套在user键下,而完全忽略wrap_parameters.

Alternatively you could just nest the parameters you send to your rails controller under the user key, and ignore wrap_parameters entirely.

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
    }
})

这篇关于在Rails中获得意外的用户参数并且无法访问密码参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆