设置redux操作的权限

时间:2016-02-08 12:58:46

标签: authentication reactjs permissions redux

我正在创建一个web redux-react应用程序,它具有许多不同的权限级别。许多用户可能正在与一个数据进行交互,但有些用户可能会对他们可以做的事情进行限制。

对我而言,设置数据交互(在应用服务器后面)的权限的显而易见的方法是将某些权限与不同的redux操作相关联。然后,当用户保存其状态时,客户端应用程序将捆绑用户操作历史记录并将其发送回服务器。然后,可以将这些操作应用于服务器中的数据,并且可以针对用户jwt检查权限,逐个操作。

这意味着很多我们的reducer代码可以在服务器上同构使用。

我找不到任何资源/讨论。在redux应用程序中处理复杂权限的常规方法是什么?纯粹在端点上使用auth似乎很麻烦,这需要重写已经在客户端减速器中编写的大量新代码。有没有理由不继续创建一个在每个动作上检查auth的减速器?

点数:

  • 我们必须假设发送到服务器的操作已经过身份验证,但是没有权限的用户会发送这些操作
  • 如果已经检查了权限并且在操作中,则reducer可以检查权限并且是纯粹的

2 个答案:

答案 0 :(得分:1)

我认为动作创建者不负责检查权限,但使用减速器和选择器绝对是最佳选择。这是一种可能的实现方式。

以下组件需要进行一些ACL检查:

$latitude = \Input::get('latitude');
$longitude = \Input::get('longitude');

$upper_latitude = $latitude + (.50); //Change .50 to small values
$lower_latitude = $latitude - (.50); //Change .50 to small values
$upper_longitude = $longitude + (.50); //Change .50 to small values
$lower_longitude = $longitude - (.50); //Change .50 to small values

$result = \DB::table('table')
        ->whereBetween('geo_locations.latitude', [$lower_latitude, $upper_latitude])
        ->whereBetween('geo_locations.logitude', [$lower_longitude, $upper_longitude])
        ->get();

我们需要将它连接到我们的商店以正确地保湿所有道具:

/**
 * Display a user record.
 * 
 * A deletion link is added if the logged user has sufficient permissions to
 * delete the record.
 */
function UserRecord({ username, email, avatar, isGranted, deleteUser }) {
  return (
    <div>
      <img src={avatar} />
      <b>{username}</b>
      {isGranted("DELETE_USER")
        ? <button onClick={deleteUser}>{"Delete"}</button>
        : null
      }
    </div>
  )
}
  • export default connect( (state) => ({ isGranted: (perm) => state.loggedUser.permissions.has(perm), }), {deleteUser}, (stateProps, dispatchProps, ownProps) => ({ ...stateProps, ...ownProps, deleteUser: () => dispatchProps.deleteUser(ownProps.user) }) )(UserRecord) 的第一个参数将为已登录的用户创建connect。可以使用isGranted来完成此部分以提高性能。

  • 第二个参数将绑定操作。没什么好看的。

  • 第三个参数将合并所有道具并将它们传递给包装组件。 reselect与当前记录绑定。

您现在可以使用deleteUser而无需处理ACL检查,因为它会根据UserRecord中存储的内容自动更新。

loggedUser

为了获得上述示例工作,您需要将记录的用户存储在Redux的商店中<UserRecord user={someUser} /> 。您不需要检查ACL操作,因为如果当前用户缺少权限,UI将不会触发它们。此外,必须在服务器端检查ACL。

答案 1 :(得分:1)

您可以设置一个辅助函数,该函数将内置到用于检查用户权限(本地或远程)的操作中,您还将在出错时提供回调操作创建者。当然,需要redux-thunk或类似内容,以便您可以从其他操作中调度操作。

您应该遵守的关键规则是:

Reducers是纯函数

动作创作者可以不纯。这意味着减少器总是在给定相同参数的情况下返回相同的值。在reducer中检查ACL权限将违反该规则。

假设你说你需要获取联系人列表。您的行动是REQUEST_CONTACTS。动作创建者首先会发送类似的内容:

// ACL test function
function canAccessContacts(dispatch) {
    if (user !== 'cool') {
        dispatch({type: 'ACCESS_DENIED'});
        return false;
    }
}

// Action creator
function fetchContacts() {
    return (dispatch) => {
        if (!canAccessContacts(dispatch)) {
            return false;
        }

        // your logic for retrieving contacts goes here
        dispatch({
            type: 'RECEIVE_CONTACTS',
            data: your_contacts_data_here
        });
      };
}
有数据后,

RECEIVE_CONTACTS将被解雇。 REQUEST_CONTACTSRECEIVE_CONTACTS之间的时间(可能是异步调用)无法显示您的加载指标。

当然,这是一个非常原始的例子,但它应该让你去。