Signature.php
4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?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;
// string: token.
private $token;
// array: sign header.
private $signHeader;
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',
'expires',
'host',
'if-match',
'if-modified-since',
'if-none-match',
'if-unmodified-since',
'origin',
'range',
'transfer-encoding',
'pic-operations',
];
date_default_timezone_set($this->options['timezone']);
}
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;
}
}