努力用 rails 后端、react + redux 前端实现设计用户角色
Struggling to implement Devise user roles with rails backend, react + redux frontend
我正在构建一个应用程序,其中有两种类型的用户,member
和 business_event
。我正在努力实施这一点。我有一个用户注册表单,无论他们是“会员”还是“企业或活动”,他们都可以从下拉菜单中 select。当我尝试注册特定角色时,我的 rails 控制台始终显示“角色”是“成员”(我分配的默认值)。
在我的 rails 后端,我添加了设计 gem 和这个迁移:
class AddRoleToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :role, :integer
end
end
然后我将 User
模型更改为以下内容:
class User < ApplicationRecord
has_secure_password
enum role: [:member, :business_event]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :member
end
end
在我的 React 前端,这是我想用来注册用户的表单:
import React from 'react'
import { connect } from 'react-redux'
import { updateSignupForm } from "../../actions/signupForm.js"
import { signup } from "../../actions/currentUser.js"
const Signup = ({ signupFormData, updateSignupForm, signup }) => {
const handleUserInfoInputChange = event => {
const { name, value } = event.target
const updatedFormInfo = {
...signupFormData,
[name]: value
}
updateSignupForm(updatedFormInfo)
}
const handleSubmit = event => {
event.preventDefault()
signup(signupFormData)
}
return (
<div>
<h1>Sign Up </h1>
<form onSubmit={handleSubmit}>
<div className="ui input">
<select>
<option value={signupFormData.role}>Member</option>
<option value={signupFormData.role}>Business or Event</option>
</select>
<input placeholder="username" value={signupFormData.username} name="username" type="text" onChange={handleUserInfoInputChange} />
<input placeholder="password" value={signupFormData.password} name="password" type="text" onChange={handleUserInfoInputChange} />
<input placeholder="email" value={signupFormData.email} name="email" type="text" onChange={handleUserInfoInputChange}/><br/><br/>
<button className="button button-signup" type="submit" value="Sign Up" > Sign up</button>
</div>
</form>
</div>
)
}
const mapStateToProps = state => {
return {
signupFormData: state.signupForm
}
}
export default connect(mapStateToProps, { updateSignupForm, signup } )(Signup)
在我的 signupForm
reducer 中,我决定将“role”的初始值设置为“0”,因为它在后端是一个整数。我不确定那是否是我出错的地方:
const initialState = {
username: "",
password: "",
email: "",
role: 0
}
export default (state=initialState, action) => {
switch (action.type) {
case "UPDATE_SIGNUP_FORM":
return action.formData
case "RESET_SIGNUP_FORM":
return initialState
default:
return state
}
}
我不确定为什么用户总是恢复到默认角色“成员”。任何帮助将不胜感激。
在添加其他功能之前,您真的应该只专注于正确安装 Devise 并为您的基本身份验证系统添加测试。收起你的工作并回溯。
首先运行生成器生成配置文件:
rails g devise:install
然后设置您的模型:
rails g devise user
这增加了以下内容:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
end
您不希望 has_secure_password
这是 Rails 自己的密码加密宏来构建您自己的身份验证系统。 Devise database_authenticatable 模块可以满足您的需求。现在写 integration tests ,其中涵盖注册和登录而不涉及反应。当涉及到保持理智时,这将得到肯定的回报。
现在您可以真正开始使用角色功能了。
在数据库级别添加具有默认值的枚举列:
class AddRoleToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :role, :integer, default: 0
end
end
使用回调设置属性默认值是一种过时且老套的方法,存在许多已知缺陷。使用数据库默认值,除非你真的需要评估应用程序级别的默认值 - 在这种情况下你想通过 attributes api.
将枚举宏添加到模型中:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
enum role: [:member, :business_event]
end
如果您真的希望能够在注册用户时通过参数设置角色,您需要在 Devise 中将参数列入白名单:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:role])
end
end
但是您需要仔细考虑这样做的安全隐患,因为它可能允许恶意用户通过简单地通过 cURL 发送请求或操纵输入来授予自己更高的权限。这可能现在不相关,但如果您添加管理员角色,请记住这一点。
角色的整数值也是一个只有模型知道的实现细节。你的前端和控制器等其他一切都应该只知道键:
const initialState = {
username: "",
password: "",
email: "",
role: "member"
}
我正在构建一个应用程序,其中有两种类型的用户,member
和 business_event
。我正在努力实施这一点。我有一个用户注册表单,无论他们是“会员”还是“企业或活动”,他们都可以从下拉菜单中 select。当我尝试注册特定角色时,我的 rails 控制台始终显示“角色”是“成员”(我分配的默认值)。
在我的 rails 后端,我添加了设计 gem 和这个迁移:
class AddRoleToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :role, :integer
end
end
然后我将 User
模型更改为以下内容:
class User < ApplicationRecord
has_secure_password
enum role: [:member, :business_event]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :member
end
end
在我的 React 前端,这是我想用来注册用户的表单:
import React from 'react'
import { connect } from 'react-redux'
import { updateSignupForm } from "../../actions/signupForm.js"
import { signup } from "../../actions/currentUser.js"
const Signup = ({ signupFormData, updateSignupForm, signup }) => {
const handleUserInfoInputChange = event => {
const { name, value } = event.target
const updatedFormInfo = {
...signupFormData,
[name]: value
}
updateSignupForm(updatedFormInfo)
}
const handleSubmit = event => {
event.preventDefault()
signup(signupFormData)
}
return (
<div>
<h1>Sign Up </h1>
<form onSubmit={handleSubmit}>
<div className="ui input">
<select>
<option value={signupFormData.role}>Member</option>
<option value={signupFormData.role}>Business or Event</option>
</select>
<input placeholder="username" value={signupFormData.username} name="username" type="text" onChange={handleUserInfoInputChange} />
<input placeholder="password" value={signupFormData.password} name="password" type="text" onChange={handleUserInfoInputChange} />
<input placeholder="email" value={signupFormData.email} name="email" type="text" onChange={handleUserInfoInputChange}/><br/><br/>
<button className="button button-signup" type="submit" value="Sign Up" > Sign up</button>
</div>
</form>
</div>
)
}
const mapStateToProps = state => {
return {
signupFormData: state.signupForm
}
}
export default connect(mapStateToProps, { updateSignupForm, signup } )(Signup)
在我的 signupForm
reducer 中,我决定将“role”的初始值设置为“0”,因为它在后端是一个整数。我不确定那是否是我出错的地方:
const initialState = {
username: "",
password: "",
email: "",
role: 0
}
export default (state=initialState, action) => {
switch (action.type) {
case "UPDATE_SIGNUP_FORM":
return action.formData
case "RESET_SIGNUP_FORM":
return initialState
default:
return state
}
}
我不确定为什么用户总是恢复到默认角色“成员”。任何帮助将不胜感激。
在添加其他功能之前,您真的应该只专注于正确安装 Devise 并为您的基本身份验证系统添加测试。收起你的工作并回溯。
首先运行生成器生成配置文件:
rails g devise:install
然后设置您的模型:
rails g devise user
这增加了以下内容:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
end
您不希望 has_secure_password
这是 Rails 自己的密码加密宏来构建您自己的身份验证系统。 Devise database_authenticatable 模块可以满足您的需求。现在写 integration tests ,其中涵盖注册和登录而不涉及反应。当涉及到保持理智时,这将得到肯定的回报。
现在您可以真正开始使用角色功能了。
在数据库级别添加具有默认值的枚举列:
class AddRoleToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :role, :integer, default: 0
end
end
使用回调设置属性默认值是一种过时且老套的方法,存在许多已知缺陷。使用数据库默认值,除非你真的需要评估应用程序级别的默认值 - 在这种情况下你想通过 attributes api.
将枚举宏添加到模型中:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
enum role: [:member, :business_event]
end
如果您真的希望能够在注册用户时通过参数设置角色,您需要在 Devise 中将参数列入白名单:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:role])
end
end
但是您需要仔细考虑这样做的安全隐患,因为它可能允许恶意用户通过简单地通过 cURL 发送请求或操纵输入来授予自己更高的权限。这可能现在不相关,但如果您添加管理员角色,请记住这一点。
角色的整数值也是一个只有模型知道的实现细节。你的前端和控制器等其他一切都应该只知道键:
const initialState = {
username: "",
password: "",
email: "",
role: "member"
}