<?php namespace addons\qiniu\library; final class Auth { private $accessKey; private $secretKey; public function __construct($accessKey, $secretKey) { $this->accessKey = $accessKey; $this->secretKey = $secretKey; } public function getAccessKey() { return $this->accessKey; } public function sign($data) { $hmac = hash_hmac('sha1', $data, $this->secretKey, true); return $this->accessKey . ':' . $this->base64_urlSafeEncode($hmac); } public function signWithData($data) { $encodedData = $this->base64_urlSafeEncode($data); return $this->sign($encodedData) . ':' . $encodedData; } public function signRequest($urlString, $body, $contentType = null) { $url = parse_url($urlString); $data = ''; if (array_key_exists('path', $url)) { $data = $url['path']; } if (array_key_exists('query', $url)) { $data .= '?' . $url['query']; } $data .= "\n"; if ($body !== null && $contentType === 'application/x-www-form-urlencoded') { $data .= $body; } return $this->sign($data); } public function verifyCallback($contentType, $originAuthorization, $url, $body) { $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType); return $originAuthorization === $authorization; } public function privateDownloadUrl($baseUrl, $expires = 3600) { $deadline = time() + $expires; $pos = strpos($baseUrl, '?'); if ($pos !== false) { $baseUrl .= '&e='; } else { $baseUrl .= '?e='; } $baseUrl .= $deadline; $token = $this->sign($baseUrl); return "$baseUrl&token=$token"; } public function uploadToken($bucket, $key = null, $expires = 3600, $policy = null, $strictPolicy = true) { $deadline = time() + $expires; $scope = $bucket; if ($key !== null) { $scope .= ':' . $key; } $args = self::copyPolicy($args, $policy, $strictPolicy); $args['scope'] = $scope; $args['deadline'] = $deadline; $b = json_encode($args); return $this->signWithData($b); } /** * 上传策略,参数规格详见 * http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html */ private static $policyFields = array( 'callbackUrl', 'callbackBody', 'callbackHost', 'callbackBodyType', 'callbackFetchKey', 'returnUrl', 'returnBody', 'endUser', 'saveKey', 'insertOnly', 'detectMime', 'mimeLimit', 'fsizeMin', 'fsizeLimit', 'persistentOps', 'persistentNotifyUrl', 'persistentPipeline', 'deleteAfterDays', 'fileType', 'upHosts', ); private static function copyPolicy(&$policy, $originPolicy, $strictPolicy) { if ($originPolicy === null) { return array(); } foreach ($originPolicy as $key => $value) { if (!$strictPolicy || in_array((string)$key, self::$policyFields, true)) { $policy[$key] = $value; } } return $policy; } public function authorization($url, $body = null, $contentType = null) { $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType); return array('Authorization' => $authorization); } /** * 对提供的数据进行urlsafe的base64编码。 * * @param string $data 待编码的数据,一般为字符串 * * @return string 编码后的字符串 * @link http://developer.qiniu.com/docs/v6/api/overview/appendix.html#urlsafe-base64 */ function base64_urlSafeEncode($data) { $find = array('+', '/'); $replace = array('-', '_'); return str_replace($find, $replace, base64_encode($data)); } /** * 对提供的urlsafe的base64编码的数据进行解码 * * @param string $str 待解码的数据,一般为字符串 * * @return string 解码后的字符串 */ function base64_urlSafeDecode($str) { $find = array('-', '_'); $replace = array('+', '/'); return base64_decode(str_replace($find, $replace, $str)); } }