如何实现基于角色的 REST API
How to implement Role-based REST API
我在我的项目中有两个不同的角色:ROLE_USER
和 ROLE_ADMIN
。
我想通过 REST API's url '/users'
获取所有用户的列表,但有些字段(例如 email
)只能看到那些通过 ROLE_ADMIN
.
进行身份验证的人
所以,我通常有 2 个问题:
1) 我应该根据ROLE
决定在哪个抽象级别(在MVC
模式中)可以返回哪些信息
2) 在 Symfony 中实现这种基于角色的 REST API 的最佳方式是什么?
谢谢
由于API取决于发出请求的用户,每个请求都必须携带有关当前用户的信息。通常所有与授权相关的任务都在控制器内处理。因此,第一个问题的答案是,您应该在控制器中处理角色,并根据角色,从存储库 returned 的数据中过滤掉字段。例如,
//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 对数据数组进行编码,return 作为响应。要减少查询次数,您可以在 User class.
中添加一个 __toArray 方法
如果您正在使用 JMSSerializer
,您可以使用群组来决定可以看到或不可以看到的内容。然后在你的控制器中,或者任何地方,你可以根据角色设置组。
例如映射(在 YAML 中)..
Fully\Qualified\Class\Name:
exclusion_policy: ALL
properties:
id:
groups: [user]
userAndAdmin:
groups: [user]
adminOnly:
groups: [admin]
然后在您的控制器中将组设置为...
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;
}
虽然整个 "generateGroups" 和设置组最好放在客户视图处理程序或响应生成器中。
假设您的层次结构有 ROLE_ADMIN
作为 ROLE_USER
的父级,您将得到以下结果。
ROLE_USER
{
"users": [
{
"id": 1,
"userAndAdmin": "val"
}
]
}
ROLE_ADMIN
{
"users": [
{
"id": 1,
"userAndAdmin": "val",
"adminOnly": "val"
}
]
}
我在我的项目中有两个不同的角色:ROLE_USER
和 ROLE_ADMIN
。
我想通过 REST API's url '/users'
获取所有用户的列表,但有些字段(例如 email
)只能看到那些通过 ROLE_ADMIN
.
进行身份验证的人
所以,我通常有 2 个问题:
1) 我应该根据ROLE
决定在哪个抽象级别(在MVC
模式中)可以返回哪些信息
2) 在 Symfony 中实现这种基于角色的 REST API 的最佳方式是什么?
谢谢
由于API取决于发出请求的用户,每个请求都必须携带有关当前用户的信息。通常所有与授权相关的任务都在控制器内处理。因此,第一个问题的答案是,您应该在控制器中处理角色,并根据角色,从存储库 returned 的数据中过滤掉字段。例如,
//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 对数据数组进行编码,return 作为响应。要减少查询次数,您可以在 User class.
中添加一个 __toArray 方法如果您正在使用 JMSSerializer
,您可以使用群组来决定可以看到或不可以看到的内容。然后在你的控制器中,或者任何地方,你可以根据角色设置组。
例如映射(在 YAML 中)..
Fully\Qualified\Class\Name:
exclusion_policy: ALL
properties:
id:
groups: [user]
userAndAdmin:
groups: [user]
adminOnly:
groups: [admin]
然后在您的控制器中将组设置为...
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;
}
虽然整个 "generateGroups" 和设置组最好放在客户视图处理程序或响应生成器中。
假设您的层次结构有 ROLE_ADMIN
作为 ROLE_USER
的父级,您将得到以下结果。
ROLE_USER
{
"users": [
{
"id": 1,
"userAndAdmin": "val"
}
]
}
ROLE_ADMIN
{
"users": [
{
"id": 1,
"userAndAdmin": "val",
"adminOnly": "val"
}
]
}