<menu id="ycqsw"></menu><nav id="ycqsw"><code id="ycqsw"></code></nav>
<dd id="ycqsw"><menu id="ycqsw"></menu></dd>
  • <nav id="ycqsw"></nav>
    <menu id="ycqsw"><strong id="ycqsw"></strong></menu>
    <xmp id="ycqsw"><nav id="ycqsw"></nav>
  • api管理系統php源碼(Api 國內PHP開源接口框架)


    上一章起了個頭,這一章咱們親身做一下這個API的基礎結構。

    我們給它叫做“老趙API系統”。

    首先,我們要做的這個API系統是私有的,不開源的,不分發給其它人一起用(當然你非要大力推廣,也隨便你)。

    其次,我故意遺漏了一個小小的點子,這個點子我自己用,我也是怕我這個辦法泄露后會有安全問題。

    就當是拋磚引玉吧。

    先說要注意的幾點:

    0、不要使用默認首頁

    1、不使用SESSION和COOKIE

    2、每次訪問都需要驗證用戶名密碼

    3、任何單個文件都不允許能正常運行

    4、任何單個文件都不允許能單獨實現任何功能

    5、未驗證成功身份時不輸出任何錯誤提示

    相信很多高人一看這幾條就會知道我要怎么做。也會有一部分人會嗤之以鼻說太初級。

    管他呢,反正這是我自己摸索出來的,就是黑客黑我也只能在操作系統方面下手,在我這套系統里他永遠不可能有成功的訪問請求。

    下面詳細說:

    0、不要使用默認首頁。

    如果你的環境里首頁設置了很多,比如index.php,index.html,default.html,default.php之類的,那么你API的接口文件一定不能用這些,比如你可以用iLaoZhao_XX_api.php,這誰猜得到?

    1、不使用SESSION和COOKIE。

    COOKIE是用明文存在于用戶端的,很容易查看和修改,這個大家都清楚。而PHP的SESSION也依賴于COOKIE來存儲一個SESSION_ID。并且我們的API要每次訪問就返回一次數據,很多訪問方法并不會存儲COOKIE,這會導致SESSION失效。

    2、每次訪問都驗證用戶名密碼。

    現在流行那個啥叫Token的方式,我懶得研究,倒不如每次都驗證用戶名和密碼,這樣等密碼泄露后只要我改一個密碼,他那邊立馬就不能用了。都不用等他那邊信息過期。當然我們不能明文傳遞這些東西,需要做一定加密處理。

    3、任何單個文件都不允許能正常運行。

    資源文件夾不能有任何可執行文件。并且盡量多分幾個文件,所有的文件相互依賴,并且把它們互相組織起來的文件又是另一個單獨文件,這樣即便別人知道了我們的文件路徑和文件名,當訪問這個文件時,也無法正常運行。

    4、任何單個文件都不允許能單獨實現任何功能。

    某個文件要實現功能,必須依賴其它文件內的函數或類,并且當前文件不能知道這些函數和類具體在哪個文件里實現的。這樣即便這個文件的源代碼泄露,對方也不知道里面的依賴關系,不會連累到其它文件。

    5、未驗證成功身份時不輸出任何錯誤提示。

    在用戶名密碼出錯時,系統不要輸出任何有用的信息,或者輸出一個假的404信息,這樣別人在試探我們的系統時,根本不知道是哪一步出錯了,而我們的客戶端可以根據里面的暗語來判斷狀態。

    我做一個小例子來說明一下,這個小例子只是拋磚引玉,并不是我最終的代碼樣子。

    文件樹結構:如何用PHP寫一個比較安全的API系統(實現)

    老趙API文件樹結構

    根目錄下只有一個文件夾,整個API系統都通過一個接口文件”DaYeLaiWanA.php”來調用。

    怎么樣,不知道文件結構的人根本猜不對你有哪些文件,也就不能訪問任何文件。

    下面的代碼沒有使用太先進的語法,比如類和對象啊命名空間啊啥的,新版本PHP添了好多特性,但我比較傾向于不去使用它們,我要盡量的讓代碼對環境沒有要求,在盡可能多的版本環境下都能運行。

    畢竟我們要的是安全,而不是讓所有人能讀懂我們的代碼。

    我們要盡可能的不使用教科書上的通用的寫法,盡可能搞一套自己的寫法。

    下面是DaYeLaiWanA.php的代碼:

    <?php
    //接口文件,單獨調用這個文件沒任何作用,參數必須得對,差一個字母這個文件都運行不出個毛線來。
    //而參數是你自己定的,可隨意加密修改。
    
    //當然你還可以把這個路徑也放到變量里,然后藏起來。
    include "./iLaoZhao_funs/postget.php"; //沒有依賴,但也不實現任何具體功能
    include "./iLaoZhao_funs/login.php"; //依賴pdo,dbfuns,postget和接口文件
    include "./iLaoZhao_funs/curl.php"; //沒有依賴,但也不實現任何具體功能
    include "./iLaoZhao_funs/dbfuns.php"; //依賴pdo和接口文件
    //上面這些文件里涉及到安全的功能都有依賴,并且他們不知道要用的函數在哪
    //全靠這個接口文件把它們組合到一起
    //并且上面的函數里也會用到接口文件的函數(就是下面那個)
    //這些因素缺一不可,只能由接口文件來整合他們
    //上面這些文件和其它的API文件,都無法單獨運行。不是缺這就是缺那。
    
    //下面這倆函數是故意沒單獨放文件里的,為的就是其它文件缺少這個接口文件時在調用這個函數時會出錯。
    function output2Die($msg, $code = -1, $data = ''){
        $dieMsg['code'] = $code;
        $dieMsg['msg'] = $msg;
    	$dieMsg['data'] = $data;
        echo json_encode($dieMsg);
        die();
    }
    
    function isPhone($phonenumber)
    {
        return preg_match("/^1[3-9]d{9}$/", $phonenumber);
    }
    
    $area = POST("area");//要使用的API種類
    $class = POST("class");//要使用的API小分類
    $fun = POST("fun");//要使用的API功能
    
    //清理POST
    unset($_POST['area']);
    unset($_POST['class']);
    unset($_POST['fun']);
    
    if ($class !== FALSE && $fun !== FALSE){
        
    	if ($area == false){
    		$area = "public";
    	}
        
    	//生成API文件全名,這里沒加密,你可以自己變動這里。
        $incFile = dirname(__FILE__)."/{$area}/{$class}/{$fun}.php";
    
        if (file_exists($incFile)){ //檢查API文件是否存在,其實不檢查也行。
    		include "./config/pdodb.php"; //創建數據庫連接,依賴接口文件
            include $incFile;//將單獨的API文件導入進來
        }else{
    		//我因為調試的原因,顯示了錯誤信息,要求高的可以去掉。
    		output2Die("無效的請求", -1);
        }
    }else{
    	output2Die("無效的請求", -2);
    }

    文件我寫了注釋,方便大家看,實際在使用時不能有這些注釋,這些注釋只能方便別人破解我們的系統,并且這個接口文件盡可能進行代碼混淆加密。

    然后是一個獲得當前用戶信息的小例子API,這個API文件存在了
    /iLaoZhao_api/public/login/usrMsg.php里面。在調用時大概URL是這樣:

    https://你的域名/iLaoZhao_api/DaYeLaiWanA.php
    POST數據為:{
    key:"用戶名密碼時間加密字符串運算后的結果",
    class:"login",
    fun:"usrMsg",
    userName:"該用戶的用戶名"
    }

    API代碼內容usrMsg.php為:

    <?php
    //示例文件,得到當前用戶的所有信息
    //文件依賴:接口文件、數據庫連接文件、dbfuns文件、login文件
    //單獨訪問這個文件根本不能運行
    //依賴關系完全靠接口文件處理
    
    //這個API讀取post參數中的userName
    checkUserNamePassWord(); //檢查用戶名密碼,不對真接就終止運行了,對了的話就可以運行下面的代碼
    $dbArr['userName'] = POST("userName");
    if($dbArr['userName'] !== false){ //這一步沒必要,能驗證過上面那個函數,這個參數肯定存在,但我就是寫了,就是玩兒
    	//一定要用PDO的綁定功能訪問數據庫,這種方式能避免SQL注入。
    	$sql = "select * from tb_users where users_userName = :userName";
    	$rec = db_query($sql,$dbArr);
    	if($rec['count'] > 0){
    		output2Die("成功。",1,$rec);
    	}else{
    		output2Die("找不到該用戶。",-1); //要求高的,不要輸出錯誤信息。
    	}
    }
    output2Die("失敗",-2); //要求高的,不要輸出錯誤信息。

    這里面的checkUserNamePassWord()函數(在iLaoZhao_funs文件夾內的login.php文件里)也比較關鍵:

    <?php
    /**
     * 判斷用戶名密碼的函數
     此函數不允許返回東西
     調用的時候直接調用
     用戶正常自然沒反應
     用戶不正常,這個函數直接結束程序運行。
     */
    function checkUserNamePassWord(){
    	$keyStr = "這里是加密字符串,這個串只有你自己知道是什么。";
    	
    	$key = POST("key"); //這個key是客戶端把用戶名密碼時間加密字符串運算后的結果
    
    	//用當前日期當第二密鑰,這個作用是每天的密鑰都不一樣。
    	//即便被攔截了,也算不出規律來,當然源碼泄露了就不行了。
    	//不能太精確,因為客戶端與服務器端的時間不可能完全一樣。
    	$keyStr_Today = date('Ymd',time());
    	
    	//訪問數據庫,一定要用PDO的這個參數方式。
    	//這個方式在代入數據與直接寫在SQL語句里不一樣。
    	//sql注入在這種使用方式下完全不會生效。
    	$sqlPar['username'] = POST("userName"); //這個沒加密的必要,這個在輸入框里就能看到,而且也會在很多地方顯示。
    	if($sqlPar['username'] === false || $key === false){
    		//非法調用
    	}
    	
    	//不要在sql里直接比對用戶名密碼
    	//而且傳過來的數據也沒有密碼
    	//要取出該用戶的記錄,然后計算后與傳過來的加密身份信息對比
    	$sql = "select * from tb_users where userName=:username"; //你可以在這limit 1
    	$rec = db_query($sql, $sqlPar);
    	if($rec['count'] > 0){
    		
    		$keyInDB = md5(md5($keyStr).md5($rec['rows'][0]['userName']).md5($keyStr_Today).md5($rec['rows'][0]['passWord']));
    		//上面這句是加密方式,把加密字符串、用戶名、當前日期、密碼的MD5連接起來并再計算一次MD5
    		//當然你還可以再加點別的東西,比如字符串反轉,以及其它變量之類的。
    		//上面這句計算出來的和$key中的一樣時,說明密碼是對的。
    		if($key == $keyInDB){
    			//用戶名密碼對
    			//此時我們啥也不做
    			//或者你想設置某些變量也行
    		}else{
    			//否則
    			die(); //結束程序運行,
    		}
    	}
    }

    代碼里都有注釋,應該能看清楚。而且還有其它的自定義函數我就不放代碼了。

    這樣我們在擴充API時只需要在對應路徑下寫PHP代碼文件就行,而且很多函數可以直接使用,不用include任何文件。

    而且這個系統內所有的文件在單獨訪問時都會出錯(可以設置PHP不顯示錯誤信息),而接口文件在參數不正確的情況下也不會有什么具體運行結果。

    也沒有默認的首頁文檔可以訪問。

    文件路徑和文件名都沒規律,在網上都查不到參考。

    那么想黑掉這套API只有兩個辦法:

    0、黑掉服務器操作系統,再從文件系統入手。

    1、破解客戶端代碼或者攔截訪問數據,找到訪問規律。

    這兩點暫時無能為力解決。

    **邊寫文檔邊寫代碼,頭有點亂,可能有遺漏的東西,不知道大家能不能看懂。

    **此API系統還有很多地方可以進一步加密處理,但我個人感覺沒必要了。已經夠可以了。

    **此代碼沒有使用太先進的語法,比如類啊命名空間啊啥的,新版本PHP添了好多特性,但我比較傾向于不去使用它們,我要盡量的讓代碼對環境沒有要求,在盡可能多的版本環境下都能運行。

    畢竟我們要的是安全,而不是讓所有人能讀懂我們的代碼。

    有啥忘了的以后再補充吧。

    版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。

    發表評論

    登錄后才能評論
    国产精品区一区二区免费