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