淺談API開發安全之sign的唯一性(四)

如何解決sign的唯一性呢,在以往的經驗中,我們都是通過標識來確定,如果有,那就用過如果沒有那就是沒用過,當然我們還需要將sign存儲起來,這樣我們才能更好的去判斷他是否用過
存儲的話,我們有幾種方式 ,可以存在文件中,也可以存在數據庫中,更甚至,我們可以存在redis中,這裏我存在文件中,也就是 Cache 中

我們需要在校驗通過的時候 將 sign 寫入到Cache 中
那麼修改 common 類 如下:

    public function checkRequestAuth(){
        $header = request()->header();

        ##判斷header中基礎參數
        if(empty($header['sign'])){
            throw new ApiException('sign不存在',400);
        }

        if(!in_array($header['apptype'],config("app.app_types"))){
            throw new ApiException('app_type不合法',400);
        }

//         $data = [
//             'did' => $header['did'],
//             'apptype' => $header['apptype'],
//             'time' => Time::get13TimeStamp(),
//         ];
//         halt(IAuth::setSign($data));


        if(!IAuth::checkSignPass($header)){
            throw new ApiException('授權碼sign失敗',401);
        }
      ##增加到緩存文件中  config在配置文件中寫入
        Cache::set($header['sign'],1,config('app.app_sign_cache_time'));

        $this->header = $header;
    }

寫入到Cache中之後,我們需要在下次校驗的時候,獲取到這個緩存判斷他是否爲1,那麼我們需要修改下我們的 鑑權類

 public static function checkSignPass($data){
        $str = (new Aes())->decrypt($data['sign']);

        if(empty($str)){
            return false;
        }
        parse_str($str,$arr);
        if(!is_array($arr) || empty($arr['did']) || $arr['did'] != $data['did']){
            return false;
        }

        ##乘除1000增加唯一性
        if((time() - ceil($arr['time']/1000)) > config('app.app_sign_time')){
            return false;
        }
        ##判斷是否有這個緩存 有就返回false 說明這個 sign已經用過
        if(Cache::get($data['sign'])){
            return false;
        }
        return true;
    }   

這樣我們的sign就具有了唯一性 ,以上幾篇文章中,代碼的邏輯,還需要根據具體的場景進行修改,但是大致流程就是這樣,至此我們的 sign 解刨也可以告一段落了

如需瞭解更多,可以查看第一篇文章,講解sign的生成淺談API開發安全之生成sign(一)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章