132 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			132 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| 
								 | 
							
								<?php
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								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;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |