Getting Unexpected User Param and Can't access Password Param in Rails

流过昼夜 提交于 2019-12-13 20:24:08

问题


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

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

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

db schema

  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

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??


回答1:


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.

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

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


来源:https://stackoverflow.com/questions/48512933/getting-unexpected-user-param-and-cant-access-password-param-in-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!