symfony里实现resfull api并实现权限控制

11 篇文章 1 订阅

----------------------------------------------------------

1、restfull api部分

注:笔记,自己摸索出来的,路子野,仅供参考。

----------------------- 欢迎指教交流。。。

<?php
// BaseController.php

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class BaseController extends Controller
{
    protected static $method_type = array('get', 'post', 'put', 'patch', 'delete');

	/**
	 * description: 负责restfull api调派
	 * @param {request obj,class||obj,[array],string} 
	 * @return: array
	 */
	public static function restfullDispatch(Request $request,$obj,$params=null,$resouce=null){
		$resouce = $resouce ? $resouce:explode('Action',explode('Controller::',$request->get('_controller'))[1])[0];
		$method = strtolower($request->server->get('REQUEST_METHOD'));
		if (in_array($method, self::$method_type)) {
			//调用请求方式对应的方法
			$method_name = $method . ucfirst($resouce);
			if(!method_exists($obj,$method_name)){
				throw new Exception('The method: '.$method_name.' not exists!');
			}
			return $obj->$method_name($params);
		}
		return false;
	}

}

然后所有controller继承BaseController,Action调$this::restfullDispatch() 就行了,最后路由可以设置成类似:

get /admin/user

post /admin/user

put /admin/user

patch /admin/user

……

2、权限控制部分

其实也很简单,由于开始时没有认真看框架的 事件监听 部分的文档,摸索了很久。。。这里做个记录。

简单总结为以下几个步骤:

1、securty.yml里配置好角色继承关系

security:

    #···

    #分层角色
    role_hierarchy:
        ROLE_ADMIN:          ROLE_USER
        ROLE_SUPER_ADMIN:    ROLE_ADMIN
        ^ROLE_CUSTOM_:       ROLE_USER      #自定义角色需继承ROLE_USER才能登录,没错可以用正则,棒棒的

2、数据库里建立RBAC关系表(这部分基本和别的框架一样)

数据库大概是这个样子:

角色表

权限表表

 

用户表里面有一个role字段,值为角色表里的一条记录的name,就不截图了

3、监听kener.controller事件,根据role的验证权限,根据验证结果setController

<?php

namespace AppBundle\EventListener;

use Symfony\Component\HttpFoundation\Response;
// use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
// use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

use AppBundle\System\Status;
use AppBundle\Entity\Users;
use AppBundle\Entity\Roles;

/**
 * 侦听系统的kernel.controller事件,通过actionName实现权限控制
 */
class RunActionListenter
{
    protected $controllerConfig = array('Admin'); //需要进行权限控制的controller
    protected $em;
    protected $tokenStorage;
    protected $result = array(
        'code'   =>    Status::ALL['PERMISSION_DENIED'][0],
        'msg'    =>    Status::ALL['PERMISSION_DENIED'][1],
        'data'   =>    null,
    );

    public function __construct(TokenStorageInterface $tokenStorage,ContainerInterface $container){
        $this->tokenStorage = $tokenStorage;
        $this->em = $container->get('doctrine')->getManager();
    }

    public function onKernelController(FilterControllerEvent $event){
        if(! $event->isMasterRequest()){
            return;
        }
        $request = $event->getRequest();
        $isAjax = $request->isXmlHttpRequest();
        $method = strtolower($request->server->get('REQUEST_METHOD'));

        $controller = explode('Controller::',$request->get('_controller'));
        $controllerName = substr($controller[0],21);

        if(in_array($controllerName,$this->controllerConfig)){
            $user =  $this->tokenStorage->getToken()->getUser();
            //超级管理员只做登录验证,此角色可以为所欲为,并且不能通过系统的权限管理分配到此角色
            if(! $user->hasRole('ROLE_SUPER_ADMIN')){  
                $actionName = $method.ucfirst(explode('Action',$controller[1])[0]);
                $userRole = $user->getRoles()[0];
                $privileges = $this->em->getRepository(Roles::class)
                ->findOneBy(array('name'=>$userRole))->getPrivileges();
                // $privilegeId = $this->em->getRepository('AppBundle\Entity\privileges')
                // ->findOneBy(array('actionName'=>$actionName))->getId();

                if(!in_array($actionName,$privileges)){
                    $this->result['msg'] = $this->result['msg'].',你当前的职位还需要权限:'.$actionName.'才能继续访问,请【联系管理员授权】!'; 
                    $controller = $event->getController()[0];
                    $event->setController(function() use ($isAjax){
                        if($isAjax){
                            return new Response(
                                json_encode($this->result,true),
                                200,
                                array('Content-Type' => 'application/json')
                            );  
                        }else{
                            return new Response('<h4>'.$this->result['msg'].'</h4>');
                        }
 
                    });                  
                }
            }
            
        }


    }

}

然后别忘了按照文档说的在service.yml里把它写进去

-----------over。。。

------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

facing-screen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值