diff --git a/app/appserver/config/appserver.php b/app/appserver/config/appserver.php index 8f948f6070669bb1854bf78c55e94ef960c4f98c..6a7235af86665437e346453a422ee07ba7f58b39 100644 --- a/app/appserver/config/appserver.php +++ b/app/appserver/config/appserver.php @@ -22,6 +22,10 @@ return [ //'appfrontBaseTheme' => '@fecshop/app/appfront/theme/base/front', //'appfrontBaseLayoutName'=> 'main.php', 'appName' => 'appserver', + // access-token 过期时间。 + 'accessTokenTimeout' => 86400, + // 速度控制[120,60] 代表 60秒内最大访问120次, + 'rateLimit' => [120, 60], ], // language config. 'components' => [ @@ -40,12 +44,13 @@ return [ ], 'user' => [ - 'identityClass' => 'fecadmin\models\AdminUser', - 'enableAutoLogin' => true, + //'class' => 'fecshop\yii\web\User', + 'identityClass' => 'fecshop\models\mysqldb\customer\CustomerAccessToken', + ], 'errorHandler' => [ - 'errorAction' => 'site/error', + 'errorAction' => 'site/helper/error', ], 'urlManager' => [ diff --git a/app/appserver/config/modules/Customer.php b/app/appserver/config/modules/Customer.php new file mode 100644 index 0000000000000000000000000000000000000000..ca17ce00168f8d9d71823087581d26a6dd78bd77 --- /dev/null +++ b/app/appserver/config/modules/Customer.php @@ -0,0 +1,15 @@ + [ + 'class' => '\fecshop\app\appserver\modules\Customer\Module', + 'params'=> [ + ], + ] +]; \ No newline at end of file diff --git a/app/appserver/modules/AppserverController.php b/app/appserver/modules/AppserverController.php new file mode 100644 index 0000000000000000000000000000000000000000..b620e406e0909a553ee3184b88752d2eee418e62 --- /dev/null +++ b/app/appserver/modules/AppserverController.php @@ -0,0 +1,71 @@ + + * @since 1.0 + */ +class AppserverController extends FecController +{ + public $blockNamespace; + + /** + * init theme component property : $fecshopThemeDir and $layoutFile + * $fecshopThemeDir is appfront base theme directory. + * layoutFile is current layout relative path. + */ + + public function init() + { + parent::init(); + Yii::$app->user->enableSession = false; + //if (!Yii::$service->page->theme->fecshopThemeDir) { + // Yii::$service->page->theme->fecshopThemeDir = Yii::getAlias(CConfig::param('appfrontBaseTheme')); + //} + //if (!Yii::$service->page->theme->layoutFile) { + // Yii::$service->page->theme->layoutFile = CConfig::param('appfrontBaseLayoutName'); + //} + + //Yii::$service->page->translate->category = 'appfront'; + + } + + /** + * get current block + * you can change $this->blockNamespace. + */ + + public function getBlock($blockName = '') + { + if (!$blockName) { + $blockName = $this->action->id; + } + if (!$this->blockNamespace) { + $this->blockNamespace = Yii::$app->controller->module->blockNamespace; + } + if (!$this->blockNamespace) { + throw new \yii\web\HttpException(406, 'blockNamespace is empty , you should config it in module->blockNamespace or controller blockNamespace '); + } + $viewId = $this->id; + $viewId = str_replace('/', '\\', $viewId); + $relativeFile = '\\'.$this->blockNamespace; + $relativeFile .= '\\'.$viewId.'\\'.ucfirst($blockName); + + return new $relativeFile(); + } + + +} diff --git a/app/appserver/modules/AppserverModule.php b/app/appserver/modules/AppserverModule.php new file mode 100644 index 0000000000000000000000000000000000000000..c405e369110168c7f6f1ebb76b21aadb24326ec9 --- /dev/null +++ b/app/appserver/modules/AppserverModule.php @@ -0,0 +1,32 @@ + + * @since 1.0 + */ +class AppserverModule extends \yii\base\Module +{ + /* + public function init() + { + # 以下代码必须指定 + + //$this->_currentDir = __DIR__ ; + //$this->_currentNameSpace = __NAMESPACE__; + + # 指定默认的man文件 + //$this->layout = "main_ajax.php"; + parent::init(); + + } + */ +} diff --git a/app/appserver/modules/AppserverTokenController.php b/app/appserver/modules/AppserverTokenController.php new file mode 100644 index 0000000000000000000000000000000000000000..be5a3a9039b49aee74de819811140c83a47d6d6b --- /dev/null +++ b/app/appserver/modules/AppserverTokenController.php @@ -0,0 +1,73 @@ + + * @since 1.0 + */ +class AppserverTokenController extends AppserverController +{ + + public $enableCsrfValidation = false ; + + public function behaviors() + { + $behaviors = parent::behaviors(); + $behaviors['authenticator'] = [ + 'class' => CompositeAuth::className(), + 'authMethods' => [ + # ֤access_tokenʽ + //HttpBasicAuth::className(), + //HttpBearerAuth::className(), + # GET֤ķʽ + # http://10.10.10.252:600/user/index/index?access-token=xxxxxxxxxxxxxxxxxxxx + QueryParamAuth::className(), + ], + + ]; + + # rate limit֣ٶȵ + # \myapp\code\core\Erp\User\models\User::getRateLimit($request, $action){ + /* ٷĵ + ƱĬÿӦHTTPͷ ĿǰϢ + X-Rate-Limit-Limit: ͬһʱĿ; + X-Rate-Limit-Remaining: ڵǰʱʣ; + X-Rate-Limit-Reset: Ϊ˵õȴ + ԽЩͷϢͨ yii\filters\RateLimiter::enableRateLimitHeaders Ϊfalse, Ĵʾʾ + + */ + $behaviors['rateLimiter'] = [ + 'class' => RateLimiter::className(), + 'enableRateLimitHeaders' => true, + ]; + return $behaviors; + } + + public function init() + { + parent::init(); + \Yii::$app->user->enableSession = false; + } + + + + +} diff --git a/app/appserver/modules/Customer/Module.php b/app/appserver/modules/Customer/Module.php new file mode 100644 index 0000000000000000000000000000000000000000..807dd532ef6ff87c4358b1f7fc2e8dff845c864e --- /dev/null +++ b/app/appserver/modules/Customer/Module.php @@ -0,0 +1,44 @@ + + * @since 1.0 + */ +class Module extends AppserverModule +{ + public $blockNamespace; + + public function init() + { + // 以下代码必须指定 + $nameSpace = __NAMESPACE__; + // web controller + if (Yii::$app instanceof \yii\web\Application) { + $this->controllerNamespace = $nameSpace . '\\controllers'; + $this->blockNamespace = $nameSpace . '\\block'; + // console controller + //} elseif (Yii::$app instanceof \yii\console\Application) { + // $this->controllerNamespace = $nameSpace . '\\console\\controllers'; + // $this->blockNamespace = $nameSpace . '\\console\\block'; + } + //$this->_currentDir = __DIR__ ; + //$this->_currentNameSpace = __NAMESPACE__; + + // 指定默认的man文件 + //$this->layout = "home.php"; + //Yii::$service->page->theme->layoutFile = 'main.php'; + parent::init(); + } +} diff --git a/app/appserver/modules/Customer/controllers/AccountController.php b/app/appserver/modules/Customer/controllers/AccountController.php new file mode 100644 index 0000000000000000000000000000000000000000..e1f794388bab9bd15746315fd99ed45cb1a4cd2a --- /dev/null +++ b/app/appserver/modules/Customer/controllers/AccountController.php @@ -0,0 +1,34 @@ + + * @since 1.0 + */ +class AccountController extends AppserverTokenController +{ + + + public function actionIndex(){ + //echo Yii::$service->session->getUUID();exit; + $identity = Yii::$app->user->identity; + var_dump($identity['email']); + exit; + //$accessToken = Yii::$app->request->post('access_token'); + + } + + + +} \ No newline at end of file diff --git a/app/appserver/modules/Customer/controllers/JwttestController.php b/app/appserver/modules/Customer/controllers/JwttestController.php new file mode 100644 index 0000000000000000000000000000000000000000..d3649bbbb41e5252be5bcc5d8816f12e734c0c1f --- /dev/null +++ b/app/appserver/modules/Customer/controllers/JwttestController.php @@ -0,0 +1,80 @@ + + * @since 1.0 + */ +class JwttestController extends AppserverController +{ + + public function init() + { + parent::init(); + } + + public function actionIndex(){ + + $privateKey = ' +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC8kGa1pSjbSYZVebtTRBLxBz5H4i2p/llLCrEeQhta5kaQu/Rn +vuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t0tyazyZ8JXw+KgXTxldMPEL9 +5+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4ehde/zUxo6UvS7UrBQIDAQAB +AoGAb/MXV46XxCFRxNuB8LyAtmLDgi/xRnTAlMHjSACddwkyKem8//8eZtw9fzxz +bWZ/1/doQOuHBGYZU8aDzzj59FZ78dyzNFoF91hbvZKkg+6wGyd/LrGVEB+Xre0J +Nil0GReM2AHDNZUYRv+HYJPIOrB0CRczLQsgFJ8K6aAD6F0CQQDzbpjYdx10qgK1 +cP59UHiHjPZYC0loEsk7s+hUmT3QHerAQJMZWC11Qrn2N+ybwwNblDKv+s5qgMQ5 +5tNoQ9IfAkEAxkyffU6ythpg/H0Ixe1I2rd0GbF05biIzO/i77Det3n4YsJVlDck +ZkcvY3SK2iRIL4c9yY6hlIhs+K9wXTtGWwJBAO9Dskl48mO7woPR9uD22jDpNSwe +k90OMepTjzSvlhjbfuPN1IdhqvSJTDychRwn1kIJ7LQZgQ8fVz9OCFZ/6qMCQGOb +qaGwHmUK6xzpUbbacnYrIM6nLSkXgOAwv7XXCojvY614ILTK3iXiLBOxPu5Eu13k +eUz9sHyD6vkgZzjtxXECQAkp4Xerf5TGfQXGXhxIX52yH+N2LtujCdkQZjXAsGdm +B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM= +-----END RSA PRIVATE KEY----- +'; + +$publicKey = ' +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H +4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t +0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4 +ehde/zUxo6UvS7UrBQIDAQAB +-----END PUBLIC KEY----- +'; + + $token = array( + "iss" => "example.org", + "aud" => "example.com", + "iat" => 1356999524, + "nbf" => 1357000000 + ); + + $jwt = JWT::encode($token, $privateKey, 'RS256'); + echo "Encode:\n" . print_r($jwt, true) . "\n"; + + $decoded = JWT::decode($jwt, $publicKey, array('RS256')); + + /* + NOTE: This will now be an object instead of an associative array. To get + an associative array, you will need to cast it as such: + */ + + $decoded_array = (array) $decoded; + echo "Decode:\n" . print_r($decoded_array, true) . "\n"; + } + + + +} \ No newline at end of file diff --git a/app/appserver/modules/Customer/controllers/LoginController.php b/app/appserver/modules/Customer/controllers/LoginController.php new file mode 100644 index 0000000000000000000000000000000000000000..98d3f5cce5e64f8c30f46757b379dfac64afab45 --- /dev/null +++ b/app/appserver/modules/Customer/controllers/LoginController.php @@ -0,0 +1,47 @@ + + * @since 1.0 + */ +class LoginController extends AppserverController +{ + public $enableCsrfValidation = false ; + + public function actionIndex(){ + $email = Yii::$app->request->post('email'); + $password = Yii::$app->request->post('password'); + $accessToken = Yii::$service->customer->loginAndGetAccessToken($email,$password); + if($accessToken){ + echo json_encode([ + 'access-token' => $accessToken, + 'status' => 'success', + 'code' => 200, + ]); + return; + }else{ + echo json_encode([ + 'access-token' => '', + 'status' => 'error', + 'code' => 401, + ]); + return; + } + + } + + +} \ No newline at end of file diff --git a/composer.json b/composer.json index 0a3b2a2f3560be6c7abf940aeb371012402776cd..b2909f025222d04433640eddfe68ba5a896c3818 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,7 @@ "fancyecommerce/fec_admin":">=1.3.6.7", "yiisoft/yii2-mongodb": "~2.1.0" , "skeeks/yii2-assets-auto-compress": "*", + "ramsey/uuid": "*", "hightman/xunsearch": "*@beta" }, "autoload": { diff --git a/config/services/Session.php b/config/services/Session.php new file mode 100644 index 0000000000000000000000000000000000000000..587846b0de223b55d81c35e2b97b2b3933ad620d --- /dev/null +++ b/config/services/Session.php @@ -0,0 +1,30 @@ + [ + 'class' => 'fecshop\services\Session', + // 【下面的三个参数,在使用php session的时候无效】 + // 只有 \Yii::$app->user->enableSession == false的时候才有效。 + // 说的更明确点就是:这些参数的设置是给无状态api使用的。 + // 实现了一个类似session的功能,供appserver端使用 + // 【对phpsession 无效】设置session过期时间, + 'timeout' => 3600, + // 【对phpsession 无效】当过期时间+session创建时间 - 当前事件 < $updateTimeLimit ,则更新session创建时间 + 'updateTimeLimit' => 600, + // 【不可以设置phpsession】默认为php session,只有当 \Yii::$app->user->enableSession == false时,下面的设置才有效。 + // 存储引擎 mongodb mysqldb redis + 'storageEngine' => 'mysqldb', + + + //'childService' => [ + // 'session' => [ + // 'class' => 'fecshop\services\session\Session', + // ], + //], + ], +]; diff --git a/migrations/mysqldb/m170706_050701_fecshop_tables.php b/migrations/mysqldb/m170706_050701_fecshop_tables.php new file mode 100644 index 0000000000000000000000000000000000000000..e6c7cae2d1d7e51f3e0a2539508c22b657aaf050 --- /dev/null +++ b/migrations/mysqldb/m170706_050701_fecshop_tables.php @@ -0,0 +1,34 @@ +execute($sql); + } + } + + + + public function safeDown() + { + echo "m170706_050701_fecshop_tables cannot be reverted.\n"; + + return false; + } + +} diff --git a/migrations/mysqldb/m170706_091433_fecshop_tables.php b/migrations/mysqldb/m170706_091433_fecshop_tables.php new file mode 100644 index 0000000000000000000000000000000000000000..a6d84fc015f64195e45177a967dfa898d0e181d5 --- /dev/null +++ b/migrations/mysqldb/m170706_091433_fecshop_tables.php @@ -0,0 +1,53 @@ +execute($sql); + } + } + + public function safeDown() + { + echo "m170706_091433_fecshop_tables cannot be reverted.\n"; + + return false; + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m170706_091433_fecshop_tables cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/models/mysqldb/SessionStorage.php b/models/mysqldb/SessionStorage.php new file mode 100644 index 0000000000000000000000000000000000000000..99d234bdecca3ffa1f4bcbc88acb260099ad6875 --- /dev/null +++ b/models/mysqldb/SessionStorage.php @@ -0,0 +1,24 @@ + + * @since 1.0 + */ +class SessionStorage extends ActiveRecord +{ + public static function tableName() + { + return 'session_storage'; + } +} diff --git a/models/mysqldb/customer/CustomerAccessToken.php b/models/mysqldb/customer/CustomerAccessToken.php new file mode 100644 index 0000000000000000000000000000000000000000..2b280ceb378659d5c614589300ec265a2bcca908 --- /dev/null +++ b/models/mysqldb/customer/CustomerAccessToken.php @@ -0,0 +1,80 @@ + + * @since 1.0 + */ +class CustomerAccessToken extends Customer implements IdentityInterface ,RateLimitInterface +{ + + + # 速度控制 6秒内访问3次,注意,数组的第一个不要设置1,设置1会出问题,一定要 + #大于2,譬如下面 6秒内只能访问三次 + # 文档标注:返回允许的请求的最大数目及时间,例如,[100, 600] 表示在600秒内最多100次的API调用。 + public function getRateLimit($request, $action){ + $rateLimit = Yii::$app->params['rateLimit']; + if(is_array($rateLimit) && !empty($rateLimit)){ + return $rateLimit; + }else{ + return [120, 60]; + } + + } + # 文档标注: 返回剩余的允许的请求和相应的UNIX时间戳数 当最后一次速率限制检查时。 + public function loadAllowance($request, $action){ + //return [1,strtotime(date("Y-m-d H:i:s"))]; + //echo $this->allowance;exit; + return [$this->allowance, $this->allowance_updated_at]; + } + # allowance 对应user 表的allowance字段 int类型 + # allowance_updated_at 对应user allowance_updated_at int类型 + # 文档标注:保存允许剩余的请求数和当前的UNIX时间戳。 + public function saveAllowance($request, $action, $allowance, $timestamp){ + $this->allowance = $allowance; + $this->allowance_updated_at = $timestamp; + $this->save(); + } + + /** + * @inheritdoc + */ + public function behaviors() + { + return [ + TimestampBehavior::className(), + ]; + } + + +} \ No newline at end of file diff --git a/services/Customer.php b/services/Customer.php index 9bd37102be372081ea64e83056bb4f2dd94260e8..7eefbbc86c6428c59722773bb036526f7b668604 100644 --- a/services/Customer.php +++ b/services/Customer.php @@ -316,27 +316,31 @@ class Customer extends Service /** * @property $url|string + * **注意**:该方法不能在接口类型里面使用 * 在一些功能中,需要用户进行登录操作,等用户操作成功后,应该跳转到相应的页面中,这里通过session存储需要跳转到的url。 * 某些页面 , 譬如评论页面,需要用户登录后才能进行登录操作,那么可以通过这个方法把url set 进去,登录成功 * 后,页面不会跳转到账户中心,而是需要操作的页面中。 */ protected function actionSetLoginSuccessRedirectUrl($url) { - return Yii::$app->session->set($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY, $url); + return Yii::$service->session->set($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY, $url); } /** * @property $url|string + * **注意**:该方法不能在接口类型里面使用 + * **注意**:该方法不能在接口类型里面使用 * 在一些功能中,需要用户进行登录操作,等用户操作成功后,应该跳转到相应的页面中,这里通过session得到需要跳转到的url。 */ protected function actionGetLoginSuccessRedirectUrl() { - $url = Yii::$app->session->get($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY); + $url = Yii::$service->session->get($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY); return $url ? $url : ''; } /** * @property $urlKey | String + * **注意**:该方法不能在接口类型里面使用 * 登录用户成功后,进行url跳转。 */ protected function actionLoginSuccessRedirect($urlKey = '') @@ -346,8 +350,8 @@ class Customer extends Service if ($url) { // 这个优先级最高 // 在跳转之前,去掉这个session存储的值。跳转后,这个值必须失效。 - Yii::$app->session->remove($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY); - //echo Yii::$app->session->get($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY); + Yii::$service->session->remove($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY); + //echo Yii::$service->session->get($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY); //exit; return Yii::$service->url->redirect($url); } else if($urlKey) { @@ -487,4 +491,73 @@ class Customer extends Service //return $authnum; return $authnum; } + /** AppServer 部分使用的函数 + * @property $email | String + * @property $password | String + * 无状态登录,通过email 和password进行登录 + * 登录成功后,合并购物车,返回accessToken + * ** 该函数是未登录用户,通过参数进行登录需要执行的函数。 + */ + protected function actionLoginAndGetAccessToken($email,$password){ + $header = Yii::$app->request->getHeaders(); + if(isset($header['access-token']) && $header['access-token']){ + $accessToken = $header['access-token']; + } + if($accessToken){ + $identity = Yii::$app->user->loginByAccessToken($accessToken); + if ($identity !== null) { + $access_token_created_at = $identity->access_token_created_at; + $timeout = Yii::$service->session->timeout; + if($access_token_created_at + $timeout > time()){ + return $accessToken; + } + } + } + + $data = [ + 'email' => $email, + 'password' => $password, + ]; + + if(Yii::$service->customer->login($data)){ + $identity = Yii::$app->user->identity; + $identity->generateAccessToken(); + $identity->access_token_created_at = time(); + $identity->save(); + # 执行购物车合并等操作。 + Yii::$service->cart->mergeCartAfterUserLogin(); + return $identity->access_token; + + } + } + /** AppServer 部分使用的函数 + * @property $type | null or Object + * 从request headers中获取access-token,然后执行登录 + * 如果登录成功,然后验证时间是否过期 + * 如果不过期,则返回identity + * ** 该方法为appserver用户通过access-token验证需要执行的函数。 + */ + protected function actionLoginByAccessToken($type = null){ + $header = Yii::$app->request->getHeaders(); + if(isset($header['access-token']) && $header['access-token']){ + $accessToken = $header['access-token']; + } + if($accessToken){ + $identity = Yii::$app->user->loginByAccessToken($accessToken, $type); + if ($identity !== null) { + $access_token_created_at = $identity->access_token_created_at; + $timeout = Yii::$service->session->timeout; + // 如果时间没有过期,则返回identity + if($access_token_created_at + $timeout > time()){ + //如果时间没有过期,但是快要过期了,在过$updateTimeLimit段时间就要过期,那么更新access_token_created_at。 + $updateTimeLimit = Yii::$service->session->updateTimeLimit; + if($access_token_created_at + $timeout <= (time() + $updateTimeLimit )){ + $identity->access_token_created_at = time(); + $identity->save(); + } + return $identity; + } + } + } + } } diff --git a/services/Order.php b/services/Order.php index 50ea1e5e57cdfa8b33a8e141f6e8e230359bb7e1..f7cc37ed70bbea8ae36ea62846ca4f6c013d157f 100644 --- a/services/Order.php +++ b/services/Order.php @@ -536,7 +536,7 @@ class Order extends Service */ protected function actionSetSessionIncrementId($increment_id) { - Yii::$app->session->set(self::CURRENT_ORDER_INCREAMENT_ID, $increment_id); + Yii::$service->session->set(self::CURRENT_ORDER_INCREAMENT_ID, $increment_id); } /** @@ -544,7 +544,7 @@ class Order extends Service */ protected function actionGetSessionIncrementId() { - return Yii::$app->session->get(self::CURRENT_ORDER_INCREAMENT_ID); + return Yii::$service->session->get(self::CURRENT_ORDER_INCREAMENT_ID); } /** * @property $increment_id | String 订单号 @@ -564,7 +564,7 @@ class Order extends Service */ protected function actionRemoveSessionIncrementId() { - return Yii::$app->session->remove(self::CURRENT_ORDER_INCREAMENT_ID); + return Yii::$service->session->remove(self::CURRENT_ORDER_INCREAMENT_ID); } /** diff --git a/services/Session.php b/services/Session.php new file mode 100644 index 0000000000000000000000000000000000000000..e2f3a00efc497211202ad13cb0cde715b133eecd --- /dev/null +++ b/services/Session.php @@ -0,0 +1,116 @@ + + * @since 1.0 + */ +class Session extends Service +{ + // 设置session超时时间 + public $timeout; + // 当过期时间+session创建时间 - 当前事件 < $updateTimeLimit ,则更新session创建时间 + public $updateTimeLimit = 600; + // 设置 存储引擎 + public $storageEngine; + // 生成的uuid唯一标识码 + protected $_uuid; + + private $_session; + const UUID = 'fecshop_uuid'; + /** + 1. \Yii::$app->user->enableSession = false; + 查看是否是false,如果是 + + */ + public function init() + { + if(\Yii::$app->user->enableSession == true){ + $this->_session = new PhpSession; // phpsession + }else { + if ($this->storageEngine == 'mongodb') { + $this->_session = new MongoDbSession; + }else if ($this->storageEngine == 'mysqldb') { + $this->_session = new MysqlDbSession; + }else if ($this->storageEngine == 'redis') { + $this->_session = new RedisSession; + } + } + } + + /** + * 访问端: + * api访问接口,返回数据的时候,需要从 response headers 中 读取 uuid + * api 如果获取了uuid,那么下次访问的时候,需要在request header 中附带uuid信息。 + * + * 接收端: 也就是下面的函数 + * 先从 request headers 读取uuid + * 读取不到,自己生成uuid + * 最后将uuid写入response headers中 + */ + public function getUUID(){ + if(!$this->_uuid){ + $header = Yii::$app->request->getHeaders(); + $uuidName = self::UUID; + // 1.从requestheader里面获取uuid, + if(isset($header[$uuidName]) && !empty($header[$uuidName])){ + $this->_uuid = $header[$uuidName]; + }else{ // 2.如果获取不到uuid,就生成uuid + $uuid1 = Uuid::uuid1(); + $this->_uuid = $uuid1->toString(); + } + // 3.把 $this->_uuid 写入到 response 的header里面 + Yii::$app->response->getHeaders()->set($uuidName,$this->_uuid); + + } + return $this->_uuid; + } + + public function set($key,$val,$timeout=''){ + if(!$timeout && (Yii::$app->user->enableSession == false)){ + $timeout = $this->timeout; + } + return $this->_session->set($key,$val,$timeout); + } + + public function get($key,$reflush=false){ + return $this->_session->get($key,$reflush); + + } + + public function remove($key){ + return $this->_session->remove($key); + } + + + + public function setFlash($key,$val,$timeout=''){ + if(!$timeout && (Yii::$app->user->enableSession == false) ){ + $timeout = $this->timeout; + } + return $this->_session->setFlash($key,$val,$timeout); + } + + public function getFlash($key){ + return $this->_session->getFlash($key); + } + + + +} diff --git a/services/cart/Quote.php b/services/cart/Quote.php index cc125f39275acd05839589a3e8ebda266d0483c9..53e4ea529565683ce81af03135900b2dba81f31a 100644 --- a/services/cart/Quote.php +++ b/services/cart/Quote.php @@ -32,13 +32,13 @@ class Quote extends Service /** * @return int 得到cart_id * Cart的session的超时时间由session组件决定。 - * 在执行$this->CreateCart $this->mergeCartAfterUserLogin,都会执行 $this->setCartId,执行 Yii::$app->session->set(self::SESSION_CART_ID,'xxxx'); 给其赋值。 + * 在执行$this->CreateCart $this->mergeCartAfterUserLogin,都会执行 $this->setCartId,执行 Yii::$service->session->set(self::SESSION_CART_ID,'xxxx'); 给其赋值。 * 当新用户没有任何购物车操作,则返回为空值。 */ public function getCartId() { if (!$this->_cart_id) { - $cart_id = Yii::$app->session->get(self::SESSION_CART_ID); + $cart_id = Yii::$service->session->get(self::SESSION_CART_ID); $this->_cart_id = $cart_id; } @@ -199,7 +199,7 @@ class Quote extends Service { $this->_cart_id = $cart_id; - Yii::$app->session->set(self::SESSION_CART_ID, $cart_id); + Yii::$service->session->set(self::SESSION_CART_ID, $cart_id); } /** @@ -207,7 +207,7 @@ class Quote extends Service */ protected function actionClearCart() { - Yii::$app->session->remove(self::SESSION_CART_ID); + Yii::$service->session->remove(self::SESSION_CART_ID); } /** diff --git a/services/helper/Captcha.php b/services/helper/Captcha.php index 2d769c4e577252f37e789c989c14ea2c3c980a23..7fb8d1d3b089c19f531f685110b932821d36f2c7 100644 --- a/services/helper/Captcha.php +++ b/services/helper/Captcha.php @@ -108,7 +108,7 @@ class Captcha extends Service public function setSessionCode() { $code = $this->getCode($this->code); - \Yii::$app->session->set($this->_sessionKey, $code); + \Yii::$service->session->set($this->_sessionKey, $code); } //获取验证码 @@ -124,7 +124,7 @@ class Captcha extends Service public function validateCaptcha($captchaData) { $captchaData = $this->getCode($captchaData); - $sessionCaptchaData = \Yii::$app->session->get($this->_sessionKey); + $sessionCaptchaData = \Yii::$service->session->get($this->_sessionKey); return ($captchaData === $sessionCaptchaData) ? true : false; } diff --git a/services/page/Message.php b/services/page/Message.php index 099bd0b092306b4b4aca5ab668abc8ab9b2e1268..c8772f62f39599763367960e1ec23c9e4e70cd29 100644 --- a/services/page/Message.php +++ b/services/page/Message.php @@ -39,7 +39,7 @@ class Message extends Service $message = array_merge($correct, $message); } - return Yii::$app->session->setFlash($this->_correctName, $message); + return Yii::$service->session->setFlash($this->_correctName, $message); } /** @@ -59,7 +59,7 @@ class Message extends Service $message = array_merge($error, $message); } - return Yii::$app->session->setFlash($this->_errorName, $message); + return Yii::$service->session->setFlash($this->_errorName, $message); } /** @@ -90,7 +90,7 @@ class Message extends Service */ protected function actionGetCorrects() { - return Yii::$app->session->getFlash($this->_correctName); + return Yii::$service->session->getFlash($this->_correctName); } /** @@ -99,6 +99,6 @@ class Message extends Service */ protected function actionGetErrors() { - return Yii::$app->session->getFlash($this->_errorName); + return Yii::$service->session->getFlash($this->_errorName); } } diff --git a/services/product/viewLog/Session.php b/services/product/viewLog/Session.php index c0852954418094fa88e91bf230152917667eb508..bc523cdcfee3e7461503974bfef92700e585a8f7 100644 --- a/services/product/viewLog/Session.php +++ b/services/product/viewLog/Session.php @@ -14,6 +14,7 @@ use fec\helpers\CUser; use fecshop\services\Service; use Yii; /** + * **注意**:该方法不能在接口类型里面使用 * @author Terry Zhao <2358269014@qq.com> * @since 1.0 */ @@ -29,7 +30,7 @@ class Session extends Service */ public function getHistory() { - $history = Yii::$app->session->get($this->_sessionKey); + $history = Yii::$service->session->get($this->_sessionKey); return $history ? $history : ''; } @@ -52,7 +53,7 @@ class Session extends Service $logArr['user_id'] = CUser::getCurrentUserId(); } - if (!($session_history = Yii::$app->session->get($this->_sessionKey))) { + if (!($session_history = Yii::$service->session->get($this->_sessionKey))) { $session_history = []; } elseif (($count = count($session_history)) >= $this->_maxProductCount) { $unsetMaxKey = $count - $this->_maxProductCount; @@ -61,6 +62,6 @@ class Session extends Service } } $session_history[] = $logArr; - Yii::$app->session->set($this->_sessionKey, $session_history); + Yii::$service->session->set($this->_sessionKey, $session_history); } } diff --git a/services/session/MongoDbSession.php b/services/session/MongoDbSession.php new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/services/session/MysqlDbSession.php b/services/session/MysqlDbSession.php new file mode 100644 index 0000000000000000000000000000000000000000..85bd77e7c1298462fba9c294909340441125f5a0 --- /dev/null +++ b/services/session/MysqlDbSession.php @@ -0,0 +1,94 @@ + + * @since 1.0 + */ +class MysqldbSession implements SessionInterface +{ + public function set($key,$val,$timeout){ + $uuid = Yii::$service->session->getUUID(); + $one = SessionStorage::find()->where([ + 'uuid' => $uuid, + 'key' => $key, + ])->one(); + if(!$one['id']){ + $one = new SessionStorage; + $one['uuid'] = $uuid; + $one['key'] = $key; + } + $one['value'] = $val; + $one['timeout'] = $timeout; + $one['updated_at'] = time(); + $one->save(); + return true; + } + + public function get($key,$reflush){ + $uuid = Yii::$service->session->getUUID(); + $one = SessionStorage::find()->where([ + 'uuid' => $uuid, + 'key' => $key, + ])->one(); + if($one['id']){ + $timeout = $one['timeout']; + $updated_at = $one['updated_at']; + if($updated_at + $timeout > time()){ + if($reflush){ + $one['updated_at'] = time(); + $one->save(); + } + return $one['value']; + } + } + } + + public function remove($key){ + $uuid = Yii::$service->session->getUUID(); + $one = SessionStorage::find()->where([ + 'uuid' => $uuid, + 'key' => $key, + ])->one(); + if($one['id']){ + $one->delete(); + return true; + } + + } + + public function setFlash($key,$val,$timeout){ + return $this->set($key,$val,$timeout); + } + + public function getFlash($key){ + $uuid = Yii::$service->session->getUUID(); + $one = SessionStorage::find()->where([ + 'uuid' => $uuid, + 'key' => $key, + ])->one(); + if($one['id']){ + $timeout = $one['timeout']; + $updated_at = $one['updated_at']; + if($updated_at + $timeout > time()){ + + $val = $one['value']; + $one->delete(); + return $val; + } + } + } + +} \ No newline at end of file diff --git a/services/session/PhpSession.php b/services/session/PhpSession.php new file mode 100644 index 0000000000000000000000000000000000000000..daf3ad0503bb7136d619fc294df87454b81e8fd4 --- /dev/null +++ b/services/session/PhpSession.php @@ -0,0 +1,50 @@ + + * @since 1.0 + */ +class PhpSession implements SessionInterface +{ + + public function set($key,$val,$timeout){ + if($timeout){ + Yii::$app->session->setTimeout($timeout); + } + return Yii::$app->session->set($key,$val); + } + + public function get($key,$reflush){ + return Yii::$app->session->get($key); + } + + public function remove($key){ + return Yii::$app->session->remove($key); + + } + + public function setFlash($key,$val,$timeout){ + if($timeout){ + Yii::$app->session->setTimeout($timeout); + } + return Yii::$app->session->setFlash($key,$val); + } + + public function getFlash($key){ + return Yii::$app->session->getFlash($key); + } + +} \ No newline at end of file diff --git a/services/session/RedisSession.php b/services/session/RedisSession.php new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/services/session/SessionInterface.php b/services/session/SessionInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..e2e856786ff7df5af8384e836bf83fc9c039aa62 --- /dev/null +++ b/services/session/SessionInterface.php @@ -0,0 +1,27 @@ + + * @since 1.0 + */ +interface SessionInterface +{ + public function set($key,$val,$timeout); + + public function get($key,$reflush); + + public function remove($key); + + public function setFlash($key,$val,$timeout); + + public function getFlash($key); +} diff --git a/yii/filters/auth/QueryParamAuth.php b/yii/filters/auth/QueryParamAuth.php new file mode 100644 index 0000000000000000000000000000000000000000..ee4020feb7fa78f56f042f198d99be6d93afd991 --- /dev/null +++ b/yii/filters/auth/QueryParamAuth.php @@ -0,0 +1,48 @@ + + * @since 1.0 + */ +class QueryParamAuth extends YiiQueryParamAuth +{ + + /** + * д÷÷request headerжȡaccess-token + */ + public function authenticate($user, $request, $response) + { + $identity = Yii::$service->customer->loginByAccessToken(get_class($this)); + if($identity){ + return $identity; + }else{ + $result = ['status' => 'ERROR', 'code' => 401,'message' => 'token is time out']; + echo json_encode($result); + exit; + } + } + + + + + + + + + + + + +} \ No newline at end of file