接口安全防范

接口做下安全处理,封装类(待补充)

<?php
/**
 * Created by PhpStorm.
 * User: walkingsun
 * Date: 2018/2/5
 * Time: 下午9:45
 */

class apiFiter{

    private $redisObj;              //redis操作对象
    private $uniqeUser;             //唯一用户标识
    private $requestData;           //请求参数
    private $isAjax;                //是否ajax
    private $isPost;                //是否post
    private $isReSubmit;            //是否重复
    private $isVilentSubmit;        //暴力提交
    private $maxRequest;            //每分钟最大提交次数
    private $headData;              //获取头信息


    public function __construct( $uniqeUser,$redisObj,$isAjax='',$isPost='',$isReSubmit='',$isVilentSubmit='',$maxRequest=''  )
    {
        $this->redisObj =  $redisObj;
        $this->isAjax =  $isAjax;
        $this->isPost =  $isPost;
        $this->isReSubmit =  $isReSubmit;
        $this->isVilentSubmit =  $isVilentSubmit;
        $this->maxRequest =  $maxRequest?:5000;

        $this->uniqeUser = $uniqeUser;
        $this->requestData = $_SERVER['REQUEST_URI'].'_'.md5(file_get_contents("php://input"));
        $this->headData = $_SERVER;

        $this->run();
    }

    public function run(){

        if( $this->isAjax ) $this->isAjax();

        if( $this->isPost ) $this->isPost();

        if( $this->isReSubmit ) $this->isReSubmit();

        if( $this->isVilentSubmit ) $this->isVilentSubmit();



    }

    /**
     * 判断是否为ajax方式
     */
    private function isAjax(){

        if( !( isset($this->headData["HTTP_X_REQUESTED_WITH"]) && strtolower($this->headData["HTTP_X_REQUESTED_WITH"])=="xmlhttprequest" ) ){
            throw new Exception('请求不合法',400);
        }

        return true;
    }

    /**
     * 判断是否为post方式
     */
    private function isPost(){

        if( $this->headData['REQUEST_METHOD'] != 'POST' ){
            throw new Exception('请求不合法',400);
        }

        return true;
    }

    /**
     * 判断是否重复提交
     */
    private function isReSubmit(){

        $key = ($this->uniqeUser.'_'.$this->requestData);
        if( $this->redisObj->exists($key) ){
            throw new Exception('重复提交',401);
        }

        $this->redisObj->setex($key,60,'1');

        return true;
    }


    /**
     * 是否暴力提交
     */
    private function isVilentSubmit(){

        $time = date('YmdHi');
        $key = $this->uniqeUser.'_vilent';   //暴力检测key

        //存在锁定标识,返回锁定异常
        if( $this->redisObj->exist($key.'_forbidden') ){
            $limit_time = $this->redisObj->ttl($key.'_forbidden');
            throw new Exception("您的请求锁定2小时,剩余时间{$limit_time}秒",500);
        }

        //创建暴力标识
        if( !$this->redisObj->exists($key.$time) ){
            $this->redisObj->setex($key,60,0);
        }

        //获取当前暴力标识 值
        $num = $this->redisObj->get($key.$time);

        //如果分钟内的暴力标识值超过最大限制,锁定用户
        if( $num >= $this->maxRequest ){
            $this->redisObj->setex( $key.'_forbidden',7200,'' );
            throw new Exception('请求过于频繁,锁定2小时',500);
        }

        //递增标识值
        $this->redisObj->incr($key.$time);

    }
}

/*   调用实例 拦截暴力提交 */
$uniqeUser = 'userid123';
$redisObj = \Yii::$app->redis;
try{
    $apifiter = new apiFiter($uniqeUser,$redisObj,$isAjax='',$isPost='',$isReSubmit='',$isVilentSubmit=1,$maxRequest='500');
    $apifiter->run();
}catch (Exception $e){
    $errorData = ['code'=>$e->getCode(),'msg'=>$e->getMessage()];
    echo json_encode($errorData);
}

posted @ 2018-02-06 22:33  walkingSun  阅读(288)  评论(0编辑  收藏  举报
**/