一對一源碼搭建,使用文件簽名防止資源過度使用
發布來源:云豹科技 發布人:云豹科技 Date:2022-06-02 10:07:05
在當前一對一源碼搭建過程中,云存儲因為存儲量大、訪問速度快、性價比高,成為文件存儲的首選。除此之外,云存儲為了避免資源文件被過度使用,在獲取文件路徑時,通過給文件生成簽名的方式來進行驗證,保證一對一源碼文件的安全性。下面,我們就來介紹一下騰訊云存儲的文件簽名方法。
一、簽名方法
namespace Qcloud\Cos; use Psr\Http\Message\RequestInterface; class Signature { // string: access key. private $accessKey; // string: secret key. private $secretKey; // array: cos config. private $options; public function __construct( $accessKey, $secretKey, $options, $token = null ) { $this->accessKey = $accessKey; $this->secretKey = $secretKey; $this->options = $options; $this->token = $token; $this->signHeader = [ 'cache-control', 'content-disposition', 'content-encoding', 'content-length', 'content-md5', 'content-type', 'expect', 'expires', 'host', 'if-match', 'if-modified-since', 'if-none-match', 'if-unmodified-since', 'origin', 'range', 'response-cache-control', 'response-content-disposition', 'response-content-encoding', 'response-content-language', 'response-content-type', 'response-expires', 'transfer-encoding', 'versionid', ]; date_default_timezone_set( 'PRC' ); } public function __destruct() { } public function needCheckHeader( $header ) { if ( startWith( $header, 'x-cos-' ) ) { return true; } if ( in_array( $header, $this->signHeader ) ) { return true; } return false; } public function signRequest( RequestInterface $request ) { $authorization = $this->createAuthorization( $request ); return $request->withHeader( 'Authorization', $authorization ); } public function createAuthorization( RequestInterface $request, $expires = '+30 minutes' ) { if ( is_null( $expires ) || !strtotime( $expires )) { $expires = '+30 minutes'; } $signTime = ( string )( time() - 60 ) . ';' . ( string )( strtotime( $expires ) ); $urlParamListArray = []; foreach ( explode( '&', $request->getUri()->getQuery() ) as $query ) { if (!empty($query)) { $tmpquery = explode( '=', $query ); //為了保證CI的key中有=號的情況也能正常通過,ci在這層之前已經encode了,這里需要拆開重新encode,防止上方explode拆錯 $key = strtolower( rawurlencode(urldecode($tmpquery[0])) ); if (count($tmpquery) >= 2) { $value = $tmpquery[1]; } else { $value = ""; } //host開關 if (!$this->options['signHost'] && $key == 'host') { continue; } $urlParamListArray[$key] = $key. '='. $value; } } ksort($urlParamListArray); $urlParamList = join(';', array_keys($urlParamListArray)); $httpParameters = join('&', array_values($urlParamListArray)); $headerListArray = []; foreach ( $request->getHeaders() as $key => $value ) { $key = strtolower( urlencode( $key ) ); $value = rawurlencode( $value[0] ); if ( !$this->options['signHost'] && $key == 'host' ) { continue; } if ( $this->needCheckHeader( $key ) ) { $headerListArray[$key] = $key. '='. $value; } } ksort($headerListArray); $headerList = join(';', array_keys($headerListArray)); $httpHeaders = join('&', array_values($headerListArray)); $httpString = strtolower( $request->getMethod() ) . "\n" . urldecode( $request->getUri()->getPath() ) . "\n" . $httpParameters. "\n". $httpHeaders. "\n"; $sha1edHttpString = sha1( $httpString ); $stringToSign = "sha1\n$signTime\n$sha1edHttpString\n"; $signKey = hash_hmac( 'sha1', $signTime, trim($this->secretKey) ); $signature = hash_hmac( 'sha1', $stringToSign, $signKey ); $authorization = 'q-sign-algorithm=sha1&q-ak='. trim($this->accessKey) . "&q-sign-time=$signTime&q-key-time=$signTime&q-header-list=$headerList&q-url-param-list=$urlParamList&" . "q-signature=$signature"; return $authorization; } public function createPresignedUrl( RequestInterface $request, $expires = '+30 minutes' ) { $authorization = $this->createAuthorization( $request, $expires); $uri = $request->getUri(); $query = 'sign='.urlencode( $authorization ) . '&' . $uri->getQuery(); if ( $this->token != null ) { $query = $query.'&x-cos-security-token='.$this->token; } $uri = $uri->withQuery( $query ); return $uri; } }
一對一源碼通過調用createPresignedUrl方法,傳入請求文件名和簽名有效時間,就可以返回簽名字符串了。一對一源碼開發搭建并不是簡單的事,有感興趣的朋友可以繼續關注我們,了解更多開發相關知識。
聲明:以上內容為云豹科技原創,未經作者本人同意,禁止轉載,否則將追究相關法律責任www.hivedock.com
最近更新
熱門標簽