最近在研究PHP,想起之前做的一個項目,大概是這樣,通過傳輸的多個業務參數加上一個自定義簽名參數sign的方式組成加密后的URL,來簡單實現訪問的安全和權限控制。
舉例:
1、需要傳輸的參數
我們假定需要的參數:'areaCode', 'salesCode', 'orgno', 'platform','sign',其中sign用作簽名校驗。
2、接下來我們按照步驟生成鏈接
2.1、根據以下規則組合參數生成paramString
① 按參數名字母升序排列參數;
② 參數和參數值的對應方式是:<參數名>=<參數值>;
③ 用&連接符拼接多個參數。
按以上規則組合參數生成paramString的樣例:areaCode=A1111&salesCode=23456&orgno=AD00008&platform=00068
2.2、根據具體開發前約定的key值和paramString計算MD5
假設key值為“qwer00008888”,該key值僅僅用於計算MD5,不可以作為傳遞參數。
① 將paramString和“key=qwer00008888”用&拼接起來得到如下字符串:areaCode=A1111&salesCode=23456&orgno=AD00008&platform=00068&key=qwer00008888
② 計算拼接后字符串的MD5值
③ 將計算后的MD5值轉化成大寫並賦給sign參數:
sign=D61F30E1806152AFB02683A2B2B711DA
3、URL樣例
https://www.youdomain.com/path?areaCode=A1111&salesCode=23456&orgno=AD00008&platform=00068&sign=D61F30E1806152AFB02683A2B2B711DA
這時我們在服務端就可以通過sign值判斷URL是否符合我們約定的規則,如果正確就正常訪問,錯誤就跳轉到錯誤頁面。
以下是具體代碼實現:
/** * @Author: cocotsau * @CreateDate: 2018-12-18 * @UpdateDate: 2018-12-19 * @Param: paramArray, keyString, errorURL */ class URL_CHECK { /*該類可以校驗URL形如:<參數1>=<值>&<參數2>=<值>&<參數...>=<值...>&sign=<32位MD5值大寫> 支持任意個參數,按照傳入順序排列,參數值必須不為空。*/ private $url = ''; //url參數字符串 private $url_before_sign = []; //參數sign之前的字符串數組,用於計算md5值 private $md5_value = []; //參數sign簽名值數組,用於校驗是否正確 private $md5_value_correct = ''; //根據組合參數計算的md5值 private $pattern = ''; //正則表達式 public function __construct($param_array, $key, $error_page) { foreach ($param_array as $key => $value) { $this->pattern = $this->pattern . $value . '=[0-9a-zA-Z]{1,32}&'; } $this->url = parse_url($_SERVER["REQUEST_URI"], PHP_URL_QUERY); //獲取URL的參數值 //判斷URL參數是否符合約定規則 if (!preg_match_all('/^' . $this->pattern . 'sign=[0-9A-Z]{32}$/', $this->url)) { //header('Location:' . $error_page);//如果不符合規則,跳轉至錯誤頁面 echo '鏈接錯誤!'; } else { //獲取URL參數在sign之前的字符串,並插入數組 preg_match('/' . $this->pattern . '/', $this->url, $this->url_before_sign); //根據組合參數+key值計算md5值並將字母轉為大寫 $this->md5_value_correct = strtoupper(md5($this->url_before_sign[0] . 'key=' . $key)); //獲取參數sign值,插入到數組 preg_match('/(?<=sign=)[0-9A-Z]{32}/', $this->url, $this->md5_value); //判斷計算的md5值是否和sign值相等 if ($this->md5_value[0] != $this->md5_value_correct) { header('Location:' . $error_page); } else { echo '鏈接正確!'; } } } } # 傳參說明 # 1、參數數組,例如:['areaCode', 'salesCode', 'orgno', 'platform'] # 2、加密key,例如: 'qwer00008888' # 3、錯誤頁面鏈接,例如:'error.php' //我們來測試一下 $test = new URL_CHECK(['areaCode', 'salesCode', 'orgno', 'platform'], 'qwer00008888', 'error.php');
以上就是全部實現,希望對你有所幫助。