仅允许某些用户使用的强参数和变量背后的基本原理
Rationale behind strong params and variables that are only permitted for some users
我很难理解强参数。我知道它可以防止大量分配您不允许的变量。但是在 Hartl 的 tutorial 中,我还读到如果没有强参数,某人可以通过补丁请求更改例如任何用户的管理员状态(我猜这不是批量分配,因为这只是您要更改的一个值)。但是你如何为以下变量实现强参数:
- 只允许设置一次(创建新用户时)
- 一些用户应该可以更改,但其他用户不能
比如我有:
private
def user_params
params.require(:user).permit(:email,
:username,
#:verified,
#:admin,
#:moderator,
#:activated,
#:activated_at,
:password,
:password_confirmation)
end
现在,我理解的带破折号的应该是不允许的。否则用户可以通过批量分配(或其他方式)更改他们的值。
但是:
- 管理员用户(来自同一 table/controller 的特定用户)应该 能够为所有用户更改这些变量。
- 就我的应用程序而言,组织(不同的 table)应该能够授予用户版主权限,从而为用户更改这些值。
- 用户名只能在创建新用户时设置,之后绝不允许更改。现在,允许 strong_params 中的用户名是否意味着它很容易通过批量分配更改?
强参数与这些问题有什么关系?
我不是专家,但据我所知:当您设置强参数时,您通常会控制传递给 update_attributes/create 方法的内容。因此,您正在定义在以下内容中幸存的内容:
params[:user][ ... ]
在 admin
更新 user
的情况下,你不需要 POST 整个用户对象,你可以简单地调用一个特定的函数将更改您要更改的任何 user
属性。换句话说:
$.ajax(
{ "method": "PUT", "url": "/users/" + uid },
{ "task": "make_admin" }
);
在你的控制器中:
def update
if params[:task] == "make_admin" && user_is_authorized
User.find(params[:id]).admin = true
end
end
虽然最简单的情况是 user_params
总是做同样的事情并被所有对 update_attributes
的调用使用,但这只是最简单的情况。
根据当前用户的权限进行许可或为不同的操作设置不同的许可列表是非常明智的(因此可能只有创建操作中使用的许可列表允许:username
)。
您可以考虑的另一种模式是为具有管理访问权限的用户提供的 Admin 命名空间:Admin::UsersController
将允许更改更多字段,并可能公开普通用户不应访问的更多功能或数据。
我很难理解强参数。我知道它可以防止大量分配您不允许的变量。但是在 Hartl 的 tutorial 中,我还读到如果没有强参数,某人可以通过补丁请求更改例如任何用户的管理员状态(我猜这不是批量分配,因为这只是您要更改的一个值)。但是你如何为以下变量实现强参数:
- 只允许设置一次(创建新用户时)
- 一些用户应该可以更改,但其他用户不能
比如我有:
private
def user_params
params.require(:user).permit(:email,
:username,
#:verified,
#:admin,
#:moderator,
#:activated,
#:activated_at,
:password,
:password_confirmation)
end
现在,我理解的带破折号的应该是不允许的。否则用户可以通过批量分配(或其他方式)更改他们的值。
但是:
- 管理员用户(来自同一 table/controller 的特定用户)应该 能够为所有用户更改这些变量。
- 就我的应用程序而言,组织(不同的 table)应该能够授予用户版主权限,从而为用户更改这些值。
- 用户名只能在创建新用户时设置,之后绝不允许更改。现在,允许 strong_params 中的用户名是否意味着它很容易通过批量分配更改?
强参数与这些问题有什么关系?
我不是专家,但据我所知:当您设置强参数时,您通常会控制传递给 update_attributes/create 方法的内容。因此,您正在定义在以下内容中幸存的内容:
params[:user][ ... ]
在 admin
更新 user
的情况下,你不需要 POST 整个用户对象,你可以简单地调用一个特定的函数将更改您要更改的任何 user
属性。换句话说:
$.ajax(
{ "method": "PUT", "url": "/users/" + uid },
{ "task": "make_admin" }
);
在你的控制器中:
def update
if params[:task] == "make_admin" && user_is_authorized
User.find(params[:id]).admin = true
end
end
虽然最简单的情况是 user_params
总是做同样的事情并被所有对 update_attributes
的调用使用,但这只是最简单的情况。
根据当前用户的权限进行许可或为不同的操作设置不同的许可列表是非常明智的(因此可能只有创建操作中使用的许可列表允许:username
)。
您可以考虑的另一种模式是为具有管理访问权限的用户提供的 Admin 命名空间:Admin::UsersController
将允许更改更多字段,并可能公开普通用户不应访问的更多功能或数据。