问题
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