php生成appid,PHP生成騰訊云COS簽名

目標

使用 PHP 創建 COS 接口所需要的請求簽名

步驟

按照官方示例(也許是我笨,我怎么讀都覺得官方文檔結構費勁,示例細節互相不挨著,容易引起歧義),請求簽名應用在需要身份校驗的場景,即非公有讀權限時。否則在請求API接口時,就必須攜帶簽名作為請求頭的一部分傳遞。

準備好用戶信息

將會使用到的用戶信息包括:

SecretId:騰訊云賬號內分配

SecretKey:騰訊云賬號內分配

Bucket:存儲桶名稱

Region:區域,即該COS所屬區域

FileUri:請求路徑,如PUT /textfile HTTP1.1,意思是將新上傳的文件放在目標存儲桶根目錄下并命名為textfile

Host:主機,存儲桶具體訪問地址,騰訊云存儲桶詳情可以找到

Content-Length:上傳文件時必須的請求頭

創建參數

先看一個官方文檔給出的栗子

通過 RESTful API 對 COS 發起的 HTTP 簽名請求,使用標準的 HTTP Authorization 頭部來傳遞,如下例所示:

PUT /testfile2 HTTP/1.1

Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com

x-cos-content-sha1: 7b502c3a1f48c8609ae212cdfb639dee39673f5e

x-cos-storage-class: standard

Hello world

解讀一下,這是一個很簡單的http請求,第一行是請求行,第二、三、四行都是請求頭,先放在這兒,后面會用到。按照官方文檔,先準備好必需的參數,參數均已鍵值對方式存在,首先看看官方給出的完整簽名結構

q-sign-algorithm=sha1&q-ak=[SecretID]&q-sign-time=[SignTime]&

q-key-time=[KeyTime]&q-header-list=[SignedHeaderList]&

q-url-param-list=[SignedParameterList]&q-signature=[Signature]

文本中每一個方括號中的內容就是用戶信息,其實sha1也是一個參數截止到發文官方文檔表示只支持sha1因此直接填寫即可,其它的以下逐一解讀

q-xxx:參數中的鍵,固定值,接口設定

[SecretID]:對應客戶的SecretId,如AKIDQjz3ltompVjBni5LitkWHFlFpwkn9U5q

[SignTime]:一個由本簽名起始時間和結束時間組成的字符串,官方文檔解釋的很清楚,不再贅述

[KeyTime]:與[SignTime]相同

[SignedHeaderList]:HTTP請求頭所組成,官方文檔說明需從 key:value 中提取部分或全部 key...,第一次沒有理解怎么還允許部分,到底是全部還是部分。再次研究接口時,明白了,數據來自對接口的原始請求,即還沒計算簽名前的HTTP Request Headers。往回倒兩步來看2. 創建參數開始時給出的請求示例。Host、x-cos-content-sha1、x-cos-storage-class說明該請求全部請求頭有三個,因此[SignedHeaderList]可以有這三個請求頭組成,也可以挑兩個甚至一個(我按照理論猜測未測試)。該值是由請求頭的Key部分組成,Key需轉化為小寫并且以字典排序再用連接符;連接,正確處理后的結果應該是host;x-cos-content-sha1;x-cos-storage-class。當然如果有Content-Type這樣的請求頭,結果應為content-type;host;x-cos-content-sha1;x-cos-storage-class。

[SignedParameterList]:官方文檔說明該值來自接口中的HTTP請求部分,即第一行請求行。官方給出的例子是HTTP請求GET /?prefix=abc&max-keys=20時,[SignedParameterList]為max-keys;prefix或prefix。按字面意思如果是非GET請求應該就沒有查詢部分也就沒有參數,該值應該是空。

[Signature]:使用特定的算法計算出的簽名字符串,后面細說。

編寫

根據上面的結構分解,可以了解到以下結構

請求簽名是由7個鍵值對組成的字符串

請求簽名最后一個值[Signature]需要進一步計算

在創建請求簽名之前,HTTP原始請求頭最好就設計好包括哪些字段,最好只包括最必要的如Host,因為原始請求頭將作為一種數據源影響請求簽名的計算結果

了解了結構之后,開始創建一個簽名,為了和官方文檔比對結果,用戶信息使用官方文檔給出的內容

用戶信息

APPID:1254000000(在計算請求簽名的過程中我沒發現該參數有什么用)

SecretId:AKIDQjz3ltompVjBni5LitkWHFlFpwkn9U5q

SecretKey:BQYIM75p8x0iWVFSIgqEKwFprpRSVHlz

Bucket:bucket1-1254000000

Region:ap-beijing

FileUri:/testfile2

Host:bucket1-1254000000.cos.ap-beijing.myqcloud.com(Host的構造可以從官方給出的示例自行組成或拆分)

Content-Length:示例中未有此項

x-cos-content-sha1: 7b502c3a1f48c8609ae212cdfb639dee39673f5e

x-cos-storage-class: standard

請求簽名結果比照

根據用戶信息,帶入到請求簽名結構中,對應關系如下

鍵(key)

值(value)

備注

q-sign-algorithm

sha1

目前僅支持 sha1 簽名算法

q-ak

AKIDQjz3ltompVjBni5LitkWHFlFpwkn9U5q

SecretId 字段

q-sign-time

1417773892;1417853898

2014/12/5 18:04:52 到 2014/12/6 16:18:18

q-key-time

1417773892;1417853898

2014/12/5 18:04:52 到 2014/12/6 16:18:18

q-header-list

host;x-cos-content-sha1;x-cos-storage-class

HTTP 頭部 key 的字典順序排序列表

q-url-param-list

HTTP 參數列表為空

q-signature

14e6ebd7955b0c6da532151bf97045e2c5a64e10

通過代碼計算所得

以上是官方文檔給出的“結果”,也就是說如果自己計算出來的7個鍵值對跟表格中結果一致,即說明算法正確。

先計算已有的值

/**

* 計算簽名

* secretId、secretKey 為必需參數,qSignStart、qSignEnd為調試需要,測試通過后應取消,改為方法內自動創建

*/

function get_authorization( $secretId, $secretKey, $qSignStart, $qSignEnd, $fileUri, $headers ){

/*

* 計算COS簽名

* 2018-05-17

* author:cinlap

* ref:https://cloud.tencent.com/document/product/436/7778

*/

$qSignTime = "$qSignStart;$qSignEnd"; //unix_timestamp;unix_timestamp

$qKeyTime = $qSignTime;

$header_list = get_q_header_list($headers);

//如果 Uri 中帶有 ?的請求參數,該處應為數組排序后的字符串組合

$url_param_list = '';

//compute signature

$httpMethod = 'put';

$httpUri = $fileUri;

//與 q-url-param-list 相同

$httpParameters = $url_param_list;

//將自定義請求頭分解為 & 連接的字符串

$headerString = get_http_header_string( $headers );

// 計算簽名中的 signature 部分

$signTime = $qSignTime;

$signKey = hash_hmac('sha1', $signTime, $secretKey);

$httpString = "$httpMethod\n$httpUri\n$httpParameters\n$headerString\n";

$sha1edHttpString = sha1($httpString);

$stringToSign = "sha1\n$signTime\n$sha1edHttpString\n";

$signature = hash_hmac('sha1', $stringToSign, $signKey);

//組合結果

$authorization = "q-sign-algorithm=sha1&q-ak=$secretId&q-sign-time=$qSignTime&q-key-time=$qKeyTime&q-header-list=$header_list&q-url-param-list=$url_param_list&q-signature=$signature";

return $authorization;

}

為了測試,該方法參數應該是多過需要了,前六個參數是已經給出的,是來自用戶的,因此直接賦值即可

$authorization = "q-sign-algorithm=sha1&q-ak=$secretId&q-sign-time=$qSignTime&q-key-time=$qKeyTime...

q-header-list

這個值需要計算,邏輯是從HTTP請求頭中,選擇全部或部分,將每項的key轉化為小寫并按字典排序,最終輸出成字符串,多個key用字符 ; 連接。代碼如下

```php

/**

按COS要求對header_list內容進行轉換

提取所有key

字典排序

key轉換為小寫

多對key=value之間用連接符連接

*/

function get_q_header_list($headers){

if(!is_array($headers)){

return false;

}

try{

$tmpArray = array();

foreach( $headers as $key=>$value){

array_push($tmpArray, strtolower($key));

}

sort($tmpArray);

return implode(';', $tmpArray);

}

catch(Exception $error){

return false;

}

}

本例中,HTTP請求頭是三個,因此輸出結果應該是host;x-cos-content-sha1;x-cos-storage-class```,和官方給出結果一致。

q-url-param-list

上面講過,這個值是HTTP請求參數,對于PUT方法沒有?后參數,自然值為0,所以代碼中“偷懶”直接給了空字符串,實際應該根據用戶給的URI做個智能判斷之類的,但是想想從邏輯上不做也行。

最后重點是計算 Signature

算法官方已經給出了,PHP還是很幸福的直接拿來用,先看一下 $httpString 的組成。由四個部分組成 $httpMethod、 $httpUri、 $httpParameters、 $headerString。

$httpMethod:HTTP請求方法,小寫,比如 put、get

$httpUri:HTTP請求的URI部分,從“/”虛擬根開始,如 /testfile 說明在存儲桶根目錄下創建一個叫 testfile 的文件,/image/face1.jpg 說明在根目錄/image目錄下建立一個叫 face1.jpg 的文件,至于是不是圖片文件,不管

$httpParameters:HTTP請求參數,即請求URI中?后面的部分,本例調用的是 PUT Object 接口,因此為空

$headerString:這個地方就需要計算了,邏輯是根據請求頭,選擇全部或部分請求頭,把每項的key都轉換為小寫,把value都進行URLEncode轉換,每項格式都改為key=value,然后按照key進行字典排序,最后把它們用連接符 & 組成字符串。這是我整理的邏輯,代碼如下

```php

/**

按COS要求從數組中獲取 Signature 中 [HttpString] 內容

標準格式 key=value&key=value&...

數組元素按鍵字典排序 *

key轉換為小寫

value進行UrlEncode轉換

轉換為key=value格式

多對key=value之間用連接符連接

*/

function get_http_header_string($headers){

if(!is_array($headers)){

return false;

}

try{

$tmpArray = array();

foreach($headers as $key => $value){

$tmpKey = strtolower($key);

$tmpArray[$tmpKey] = urlencode($value);

}

ksort($tmpArray);

$headerArray = array();

foreach( $tmpArray as $key => $value){

array_push($headerArray, "$key=$value");

}

return implode('&', $headerArray);

}

catch(Exception $error){

return false;

}

}

```

組合輸出

至此,請求簽名中7個值都有了,有的是來自用戶信息,有的需要計算,需要計算的上面也給出了所有的計算方法和為什么如此計算的個人理解。最后只需要按照官方要求進行輸出即可。看一下

分類:

技術點:

php

By ? 2017 likecs 版權所有.

粵ICP備12038626號-2

Powered By WordPress . Theme by Luju

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396245.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396245.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396245.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

es6作用域

作用域 一個需要注意的地方是,如果參數默認值是一個變量,則該變量所處的作用域,與其他變量的作用域規則是一樣的,即先是當前函數的作用域,然后才是全局作用域。 var x 1;function f(x, y x) {console.log(y); }f(2) …

java 有參數的構造函數如何注入_Spring5參考指南:依賴注入

依賴注入依賴注入就是在Spring創建Bean的時候,去實例化該Bean構造函數所需的參數,或者通過Setter方法去設置該Bean的屬性。Spring的依賴注入有兩種基于構造函數的依賴注入和基于setter的依賴注入。基于構造函數的依賴注入構造函數的注入是通過構造函數的…

深度學習去燥學習編碼_我們問了15,000個人,他們是誰,以及他們如何學習編碼

深度學習去燥學習編碼More than 15,000 people responded to the 2016 New Coder Survey, granting researchers an unprecedented glimpse into how adults are learning to code.超過15,000人對2016年新編碼器調查做出了回應,使研究人員對成年人如何學習編碼有了前…

CentOS 7 vi編輯命令

用vi打開一個yum文件 vi /usr/bin/yum 按 i 鍵后 進入insert模式,進入insert模式后才能進行修改 修改完成后 按esc鍵進入command模式, 然后:wq 保存文件并退出vi(注意先冒號) 保存命令 按ESC鍵 跳到命令模式,然后&…

C#學習筆記四: C#3.0自動屬性匿名屬性及擴展方法

前言 這一章算是看這本書最大的收獲了, Lambda表達式讓人用著屢試不爽, C#3.0可謂顛覆了我們的代碼編寫風格. 因為Lambda所需篇幅挺大, 所以先總結C#3.0智能編譯器給我們帶來的諸多好處, 下一遍會單獨介紹Lambda表達式. 這篇主要包括的內容有: 自動屬性,隱式類型,對象集合初始化…

array keys php,php array_keys與array_search的簡單使用

函數說明array_keys():返回數組中所有的鍵名。array_search():在數組中搜索給定的值,如果成功則返回相應的鍵名。//根據一個key返回關聯數組中的另一個key,并且不使用foreach// function array_key_relative(array $array, string $current_key, int $offset)functi…

RESTful服務的第三部分:HATEOAS和Richardson成熟度模型

by Sanchit Gera通過Sanchit Gera RESTful服務的第三部分:HATEOAS和Richardson成熟度模型 (RESTful Services Part III : HATEOAS and The Richardson Maturity Model) In Part I of this series, you learned the very basics of HTTP. We went over common HTTP …

mongdb集群3.4 shard 模式

從圖中可以看到有四個組件:mongos、config server、shard、replica set。mongos:數據庫集群請求的入口,所有的請求都通過mongos進行協調,不需要在應用程序添加一個路由選擇器,mongos自己就是一個請求分發中心&#xff…

我想變得富有的10個理由

1.我想和娘家人住得近一些,可以經常見面、聊天、逛街、吃飯。我們需要彼此的時候,可以馬上趕到。 2.我想在家人病痛的時候,能得到最好的救治。 3.我想住在干凈寬敞的大房子里,不要和長輩住^_^ 4.我希望不用我動手,家里…

alpha值計算 qcolor_量化交易與機器學習(四):如何研究alpha因子

算法交易策略由指示何時購買或出售資產以產生相對于基準(例如指數)的較高回報的信號驅動。 資產回報率中未通過暴露于該基準而無法解釋的部分稱為alpha,因此旨在產生這種不相關收益的信號也稱為alpha因子。本章主要介紹alpha因子一、從數據到…

項目啟動及需求分析(靳嘉豪、胡新宇、李晨曦、楊航、李瑤)團隊作業

(1) 這次團隊我們給我們團隊起的名字是:橋上吊刀刀倒吊著 隊員分別為:靳嘉豪、胡新宇、李晨曦、李瑤、楊航。 隊訓為:黑化肥揮發發灰會揮發。 胡新宇:http://www.cnblogs.com/hxy94264/ 靳嘉豪:…

java兩種傳參,有關java參數的兩種傳遞機制

值傳遞:方法調用時,實際參數把它的值傳遞給對應的形式參數,方法執行中形式參數值的改變不影響實際參 數的值。引用傳遞:也稱為傳地址。方法調用時,實際參數的引用(地址,而不是參數的值)被傳遞給方法中相對應…

tcp選項部分編碼_學習編碼中最難的部分也是最有趣的部分

tcp選項部分編碼by Corey Slaven通過Corey Slaven 學習編碼中最難的部分也是最有趣的部分 (The hardest part of learning to code is also the funnest part) “The more you know, the more you know you don’t know.”“知道的越多,知道的越多。” ― Aristotl…

SCU 4439 Vertex Cover(二分圖最小覆蓋點)題解

題意:每一條邊至少有一個端點要涂顏色,問最少涂幾個點 思路:最小頂點覆蓋:用最少的點,讓每條邊都至少和其中一個點關聯,顯然是道裸最小頂點覆蓋題; 參考:二分圖 代碼: #i…

20155229 實驗一《Java開發環境的熟悉》實驗報告

20155229 實驗一《Java開發環境的熟悉》實驗報告 實驗內容 1.使用JDK編譯、運行簡單的Java程序; 2.使用Idea 編輯、編譯、運行、調試Java程序。 實驗步驟 (一)命令行下Java程序開發 輸入 mkdir 20155229命令建立實驗目錄,用ls查看…

js時間搓化為今天明天_js轉時間戳,時間戳轉js

js轉時間戳轉此時此刻的時間1、var timestamp1 (new Date()).valueOf();valueOf() 方法返回指定對象的原始值2、var timestamp2 new Date().getTime();Date.prototype.getTime()方法的返回值一個數值,表示從1970年1月1 日0時0分0秒(UTC,即協調世界時)距…

PHP代碼20個實用技巧(轉)

這些技巧特別是封裝的,相對路徑的還是挺好的,本身來自微信公眾號,但是我擔心以后刪除,所以在我的博客上備份一下(微信公眾號為:菜鳥教程) 在這篇文章中我們將看看一些關于PHP開發有用的提示和技巧&#xff…

需求簡報_代碼簡報:NASA將所有研究成果發布為開放數據

需求簡報Here are three stories we published this week that are worth your time:這是我們本周發布的三個值得您關注的故事: With open data, you finally get what you’ve paid for all these years: 4 minute read 有了開放的數據,您終于可以得到…

matlab 16位灰度值轉8位,在matlab中如何將灰度值為24位的轉化為8?

我使用的是Visual c6。0技術內幕里提供的類CDib來操作位圖,最好提供可以兩個獨立的函數來分辨別實現著倆個功能。他們可以作為CDib類的成員函數來使用。類似下面的這個就可以,我用了下面的這個,但是下面這個不好用,處理后的圖象有…

quartz基本使用

創建一個任務調度 Scheduler scheduler StdSchedulerFactory.getDefaultScheduler();//Schedulers can be immediately used to schedule jobs, but they will not start executing any until the .start()scheduler.start();//And then schedule those jobs with triggers th…