|
@@ -0,0 +1,123 @@
|
|
|
+<?php
|
|
|
+namespace components;
|
|
|
+
|
|
|
+use Yii;
|
|
|
+
|
|
|
+
|
|
|
+ * Class Secret
|
|
|
+ * @package components
|
|
|
+ */
|
|
|
+class Secret
|
|
|
+{
|
|
|
+ public $showErrorInfo = true;
|
|
|
+
|
|
|
+ private $_contentType = 'application/json';
|
|
|
+
|
|
|
+ private $_timeout = 300;
|
|
|
+
|
|
|
+ private $_contentMd5 = '';
|
|
|
+
|
|
|
+ private $_signatureMethod = 'md5';
|
|
|
+
|
|
|
+ private $_signatureVersion = '1.0';
|
|
|
+
|
|
|
+ private $_serverSignature = '';
|
|
|
+
|
|
|
+ private $_clientSignature = '';
|
|
|
+
|
|
|
+
|
|
|
+ * checkSignature
|
|
|
+ * @param $client_id
|
|
|
+ * @param $clientSignature
|
|
|
+ */
|
|
|
+ public function checkSignature($client_id, $clientSignature)
|
|
|
+ {
|
|
|
+ $this->_clientSignature = $clientSignature;
|
|
|
+
|
|
|
+ $cone = $this->findOne($client_id);
|
|
|
+ if (!$cone)
|
|
|
+ static::throwError("client id avail.");
|
|
|
+
|
|
|
+ $sKey = isset($client_id->client_key) ? $client_id->client_key : '';
|
|
|
+
|
|
|
+ $headers = Yii::$app->request->getHeaders();
|
|
|
+ if (!$headers)
|
|
|
+ static::throwError("headers format avail.");
|
|
|
+
|
|
|
+ $strVerb = $headers->get('verb');
|
|
|
+ if (!$strVerb || !in_array((strtoupper($strVerb)), ['POST', 'GET']))
|
|
|
+ static::throwError("headers verb avail.");
|
|
|
+
|
|
|
+ $strMd5 = $headers->get('content-md5');
|
|
|
+ if (!$this->checkContentMd5($strVerb, $strMd5, Yii::$app->request->getBodyParams()))
|
|
|
+ static::throwError("headers content md5 avail.");
|
|
|
+
|
|
|
+ $strContentType = $headers->get('content-type');
|
|
|
+ if ($strContentType !== $this->_contentType)
|
|
|
+ static::throwError("headers content type avail.");
|
|
|
+
|
|
|
+ $strDate = strtotime($headers->get('date'));
|
|
|
+ if ($strDate == false || $strDate-time() > 0 || time()-$strDate > $this->_timeout)
|
|
|
+ static::throwError("headers date avail.");
|
|
|
+
|
|
|
+ $strSM = $headers->get('signature-method');
|
|
|
+ if (strtoupper($strSM) != strtoupper($this->_signatureMethod))
|
|
|
+ static::throwError("headers signature method avail.");
|
|
|
+
|
|
|
+ $strSV = $headers->get('signature-version');
|
|
|
+ if ($strSV !== $this->_signatureVersion)
|
|
|
+ static::throwError("headers signature version avail.");
|
|
|
+
|
|
|
+ $str = "{$strVerb}\n\n{$strMd5}\n{$strContentType}\n{$strDate}\n{$strSM}\n{$strSV}\n\n{$sKey}\n";
|
|
|
+ $base_sha1 = base64_encode(hash_hmac("sha1", $str, $sKey . '&', true));
|
|
|
+
|
|
|
+ $this->_serverSignature = md5($base_sha1);
|
|
|
+ if ($this->_serverSignature != '' && $this->_serverSignature !== $this->_clientSignature)
|
|
|
+ static::throwError("Signature verification failed.");
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * findOne
|
|
|
+ * @param $client_id
|
|
|
+ */
|
|
|
+ protected function findOne($client_id = false)
|
|
|
+ {
|
|
|
+ $model = new \common\models\Client();
|
|
|
+ return $model::findOne(['client_id' => $client_id]);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * checkContentMd5
|
|
|
+ * @param $verb
|
|
|
+ * @param $md5
|
|
|
+ * @param $post
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ protected function checkContentMd5($verb, $md5, $post)
|
|
|
+ {
|
|
|
+ if ($verb == 'GET' && $md5 != '')
|
|
|
+ return false;
|
|
|
+
|
|
|
+ ksort($post);
|
|
|
+ $this->_contentMd5 = md5(json_encode($post));
|
|
|
+ if ( strtolower($md5) != strtolower($this->_contentMd5))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * throwError
|
|
|
+ * @param $msg
|
|
|
+ * @throws \yii\web\UnauthorizedHttpException
|
|
|
+ */
|
|
|
+ public function throwError($msg)
|
|
|
+ {
|
|
|
+ if ($this->showErrorInfo !== true)
|
|
|
+ throw new \yii\web\UnauthorizedHttpException('Signature error');
|
|
|
+
|
|
|
+ throw new \yii\web\UnauthorizedHttpException($msg);
|
|
|
+ }
|
|
|
+}
|