如何实现基于角色的RESTAPI

如何实现基于角色的RESTAPI,rest,symfony,model-view-controller,frameworks,roles,Rest,Symfony,Model View Controller,Frameworks,Roles,我的项目中有两个不同的角色:ROLE\u USER和ROLE\u ADMIN 我想通过REST API的url“/users””获取所有用户的列表,但某些字段(例如电子邮件)只能看到那些通过角色管理验证的人 因此,我一般有两个问题: 1) 我应该在哪个抽象级别(在MVC模式中)根据ROLE 2) 在Symfony中实现这种基于角色的restapi的最佳方法是什么 谢谢因为API依赖于发出请求的用户,所以每个请求都必须包含当前用户的信息。通常,所有与授权相关的任务都在控制器内处理。因此,第一个问

我的项目中有两个不同的角色:
ROLE\u USER
ROLE\u ADMIN

我想通过REST API的url
“/users”
”获取所有用户的列表,但某些字段(例如
电子邮件
)只能看到那些通过
角色管理验证的人
因此,我一般有两个问题:

1) 我应该在哪个抽象级别(在
MVC
模式中)根据
ROLE

2) 在Symfony中实现这种基于角色的restapi的最佳方法是什么



谢谢

因为API依赖于发出请求的用户,所以每个请求都必须包含当前用户的信息。通常,所有与授权相关的任务都在控制器内处理。因此,第一个问题的答案是,您应该在控制器中处理角色,并根据角色,从存储库返回的数据中筛选出字段。比如说,

//users is the array of user objects returned by your repository

data = [];

if ($this->get('security.context')->isGranted('ROLE_ADMIN')) {
  foreach($users as $user){
  // Add ROLE_ADMIN specific data
        data[][] = array(
            'name' => $user->getName(),
            'email' => $user->getEmail(),
        );
  }     
}


if ($this->get('security.context')->isGranted('ROLE_USER')) {
   foreach($users as $user){
    // Add ROLE_USER specific data
    data[][] = array(
        'name' => $user->getName(),
        'address' => $user->getAddress(),
               );
   } 

  }

然后,JSON对数据数组进行编码并作为响应返回。为了减少查询数量,您可以在用户类中添加一个uu toArray方法。

如果您使用的是
JMSSerializer
,您可以使用组来决定哪些内容可以查看或不查看。然后在控制器中,或者在任何地方,您都可以根据角色设置组

例如,使用映射(在YAML中)

然后在你的控制器中,你会将组设置为

public function getUsersAction(Request $request)
{
    $users = $this->getRepository()->findAll();
    $serializer = $this->get('jms_serializer.serializer');

    $json = $serializer->serialize(
        $users,
        'json',
        SerializationContext::create()->setGroups($this->generateGroups())
    );

    return new Response($json);

    // If you are using FOSRestBundle, which I would recommend, then you would just need to do...
    $view = $this
        ->view($this->getRepository()->findAll();)
        ->setExclusionGroups($this->generateGroups())
    ;

    return $this->handleView($view);
}

private function generateGroups()
{
    $securityContext = $this->get('security.context');
    $groups = array();

    if ($securityContext->isGranted('ROLE_USER')) {
        $groups[] = 'user';
    }

    if ($securityContext->isGranted('ROLE_ADMIN')) {
        $groups[] = 'admin';
    }

    return $groups;
}
尽管整个“GenerateGroup”和设置组最好放在客户视图处理程序或响应生成器中

假设您的层次结构中有
ROLE\u ADMIN
作为
ROLE\u USER
的父级,您将得到以下结果

用户角色

角色管理


谢谢你的回答。但在我看来,这样做太麻烦了。控制器中的代码会很大,很难维护。太棒了!更详细地说,我可以将它与注释一起使用,它只需几行代码。非常感谢!
public function getUsersAction(Request $request)
{
    $users = $this->getRepository()->findAll();
    $serializer = $this->get('jms_serializer.serializer');

    $json = $serializer->serialize(
        $users,
        'json',
        SerializationContext::create()->setGroups($this->generateGroups())
    );

    return new Response($json);

    // If you are using FOSRestBundle, which I would recommend, then you would just need to do...
    $view = $this
        ->view($this->getRepository()->findAll();)
        ->setExclusionGroups($this->generateGroups())
    ;

    return $this->handleView($view);
}

private function generateGroups()
{
    $securityContext = $this->get('security.context');
    $groups = array();

    if ($securityContext->isGranted('ROLE_USER')) {
        $groups[] = 'user';
    }

    if ($securityContext->isGranted('ROLE_ADMIN')) {
        $groups[] = 'admin';
    }

    return $groups;
}
{
    "users": [
        {
            "id": 1,
            "userAndAdmin": "val"
        }
    ]
} 
{
    "users": [
        {
            "id": 1,
            "userAndAdmin": "val",
            "adminOnly": "val"
        }
    ]
}