请求拦截与权限控制

EasySwoole支持在三个地方进行请求拦截,当一个HTTP请求进来,EasySwoole的执行先后顺序是:

  • Event中的OnRequest事件
  • 自定义路由(可选)
  • 控制器中的OnRequest

在以上任意位置执行 $response->end(),均不会进入下一个流程。

权限验证拦截

例如我现在 /Api/Mobile 下的全部控制器,均需要做权限控制,那么我们先建立一个全局的抽象控制器。

abstract class AbstractBase extends AbstractController
{
    protected $who;
    function onRequest($actionName)
    {
        // TODO: Implement onRequest() method.
        $cookie = $this->request()->getCookieParams(SysConst::WX_USER_COOKIE_NAME);
        if(empty($cookie)){
            $this->response()->writeJson(Status::CODE_UNAUTHORIZED);
            $this->response()->end();
        }else{
            $info = Redis::getInstance()->getConnect()->hGet(SysConst::REDIS_USER_INFO,$cookie);
            if(is_array($info)){
                if(time() - $info['time']< SysConst::WX_USER_COOKIE_TTL){
                    $this->who = $info['userBean'];
                }else{
                    $this->response()->writeJson(Status::CODE_UNAUTHORIZED);
                    $this->response()->end();
                }
            }else{
                $this->response()->writeJson(Status::CODE_UNAUTHORIZED);
                $this->response()->end();
            }
        }
    }

    function actionNotFound($actionName = null, $arguments = null)
    {
        // TODO: Implement actionNotFound() method.
        $this->response()->withStatus(Status::CODE_NOT_FOUND);
    }

    function afterAction()
    {
        // TODO: Implement afterAction() method.
    }
}

而后,我/Api/Mobile下的任意一个控制器,仅需继承该方法,即可实现权限控制。

namespace App\Controller\Api\Mobile;

class Index extends AbstractBase
{
    function index()
    {
        // TODO: Implement index() method.
        $this->response()->write($this->who->getOpenId());
    }
}

全局请求安全过滤拦截

例如,项目上线后,由于前期开发未注意安全问题,没有做参数过滤,那么,可以在Event中的OnRequest事件,进行全局的请求参数过滤或者拦截。

建立测试拦截类

namespace App\Utility;


class Security
{
    /*
     * 本注入脚本从网上流传的360 php防注入代码改版  仅供做参考
     */
    private $getFilter = "'|(and|or)\\b.+?(>|<|=|in|like)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
    private $postFilter = "\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
    private $cookieFilter = "\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
    function check(array $data){
        foreach ($data as $item){
            if (preg_match("/".$this->getFilter."/is",$item) == 1){
                return true;
            }
            if (preg_match("/".$this->postFilter."/is",$item) == 1){
                return true;
            }
            if (preg_match("/".$this->cookieFilter."/is",$item) == 1){
                return true;
            }
        }
        return false;
    }

}

在onRequest事件中调用

function onRequest(Request $request, Response $response)
{
        // TODO: Implement onRequest() method.
        $sec = new Security();
        if($sec->check($request->getRequestParam())){
            $response->write("do not attack");
            $response->end();
            return;
        }
        if($sec->check($request->getCookieParams())){
            $response->write("do not attack");
            $response->end();
            return;
        }
}

EasySwoole也支持用户使用session。

注意:以上代码仅仅做逻辑展示,请勿直接使用。

results matching ""

    No results matching ""