ApiController.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php
  2. namespace api\controllers;
  3. use common\models\RabbitLog;
  4. use components\PhpClient;
  5. use components\RabbitBase;
  6. use Yii;
  7. use yii\base\InvalidParamException;
  8. use yii\web\BadRequestHttpException;
  9. use yii\web\Controller;
  10. use yii\filters\VerbFilter;
  11. use yii\filters\AccessControl;
  12. use common\models\LoginForm;
  13. use frontend\models\PasswordResetRequestForm;
  14. use frontend\models\ResetPasswordForm;
  15. use frontend\models\SignupForm;
  16. use frontend\models\ContactForm;
  17. /**
  18. * Site controller
  19. */
  20. class ApiController extends Controller
  21. {
  22. /**
  23. * @inheritdoc
  24. /**
  25. * Displays homepage.
  26. *
  27. * @return mixed
  28. */
  29. public function actionIndex()
  30. {
  31. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  32. return [
  33. 'message' => 'API test Ok!',
  34. 'code' => 100,
  35. ];
  36. // return $this->render('index');
  37. }
  38. /**
  39. * login check
  40. *
  41. * @return mixed
  42. */
  43. public function actionMqinsert()
  44. {
  45. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  46. $params=Yii::$app->request->get();//获取参数
  47. $rabbitdata=$this->validate($params);
  48. if($rabbitdata){
  49. PhpClient::CallMq($rabbitdata);
  50. return [
  51. 'message' => 'rabbit insert Ok!',
  52. 'action' => 'insert',
  53. 'rabbitdata' => $params,
  54. 'code' => 100,
  55. ];
  56. }
  57. }
  58. /**
  59. * Displays homepage.
  60. *
  61. * @return mixed
  62. */
  63. public function actionPage()
  64. {
  65. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  66. $params=Yii::$app->request->get();//获取参数
  67. $rabbitdata=$this->validate($params);
  68. if($rabbitdata){
  69. PhpClient::CallMq($rabbitdata);
  70. return [
  71. 'message' => 'rabbit insert Ok!',
  72. 'action' => 'insert',
  73. 'rabbitdata' => $params,
  74. 'code' => 100,
  75. ];
  76. }
  77. }
  78. /**
  79. * Displays homepage.
  80. *
  81. * @return mixed
  82. *
  83. *
  84. * 登入接口修改后的分为两个步骤:
  85. 1.接收数据api,存到mq里返回ok 异步:队列开始运行调取登入接口,
  86. 如果json返回队列信息那么跟新消息信息,期间令牌保存处理状态
  87. 如果登入成功改令牌状态修改为处理完毕
  88. 2.根据令牌查找这个队列的信息
  89. *
  90. * 策略一,2个接口判断
  91. * 策略二,一个接口判断2个redis 是否还在队列中
  92. *
  93. */
  94. public function actionLogin()
  95. {
  96. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  97. $params=Yii::$app->request->get();//获取参数
  98. //不做加密校验
  99. unset($params['r']);
  100. //begin checklogin -------------
  101. //判断是否已经登入
  102. //do something 2018-01-24
  103. //end checklogin -------------
  104. $isLogin=false;//假设没有登入
  105. if(!$isLogin){
  106. //begin login -------------
  107. //redis 初始化 登入一次设置一次 所以该状态不作为登入的状态信息
  108. $redis = \Yii::$app->redis;
  109. $key = 'get-one-login-user-id-by-phone-' . $params['mobile'];
  110. // $redis->set($key,'');//暂时不需要 //退出登入是做该操作就可以 //可以多次请求接口 保持更新
  111. // die;
  112. //取出reidis的值
  113. $loginAnswer=json_decode($redis->get($key));//取出 redis的值
  114. //如果 有数据 则判断是否被 队列处理 获取了 登入结果信息
  115. //开始判断
  116. if(empty($loginAnswer)){//如果是空说明第一次
  117. //判断该接口第一次请求登入该用户,并且队里中没有该用户登入的处理队里消息
  118. //传入mq中同步
  119. //如果没有请求则 插入请求状态 标识 请求处理中
  120. $loginAnswer=[
  121. 'message' => 'handing',
  122. 'code' => 102,//表示队里还没有处理到 需要再次请求以获取处理结果
  123. 'status' =>200,
  124. 'rabbit'=>'handing'
  125. ];
  126. //插入redis 标识 改请求已经 在处理中了
  127. $redis->set($key,json_encode($loginAnswer));
  128. $insertMq=RabbitBase::CallMq(json_encode($params)) ;//插入队列
  129. if($insertMq){
  130. //取出reidis的值
  131. //因为队列消息处理处理速度可能和 上下文时间同时发生所以在此校验 一下该信息是否已经被队列处理完成避免多次网络请求
  132. $loginAnswer=json_decode($redis->get($key));
  133. //获取到储存在redis里面消费队列请求的结果并且返回给前段,如果消息队列里面没有放入到redis里面则判断为没有操作登入返回登入失败处理
  134. }
  135. }else{
  136. //用户显示一次刷新一次 如果是单个用户第二次请求不同的token
  137. // var_dump($loginAnswer);die;
  138. if($loginAnswer->code!=102){
  139. $loginAnswer=json_decode($redis->get($key));
  140. $redis->set($key,''); //可以多次请求接口 保持更新
  141. }
  142. }
  143. //不是第一次 直接返回redis内容 因为 队列消费已经处理保存进去了
  144. //end login -------------
  145. }else{
  146. $loginAnswer=[
  147. 'message' => 'have logined',
  148. 'code' => 101,
  149. 'status' => 200,//表示队里还没有处理到 需要再次请求以获取处理结果
  150. 'rabbit'=>'you have logined'
  151. ];
  152. }
  153. return $loginAnswer;
  154. }
  155. /**
  156. * Displays homepage.
  157. *
  158. * @return mixed
  159. */
  160. private function validate($params)
  161. {
  162. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  163. if(isset($params["signature"]) && isset($params["timestamp"]) && isset($params["rabbitdata"])){
  164. $signature = $params["signature"];//本地签名
  165. $timestamp = $params["timestamp"];//时间戳
  166. $rabbitdata = $params["rabbitdata"];//rabbitdata 存入mq中的数据
  167. unset($params['r'],$params['signature'],$params['rabbitdata']);
  168. //valid signature , option
  169. if($this->checkSignature($params,$timestamp,$signature)){
  170. return $rabbitdata;//返回rabbitdata
  171. }else if(!$this->checkRabbitdata($rabbitdata)){
  172. return false;
  173. }else{
  174. exit(json_encode([
  175. 'message' => 'signature test fail!',
  176. 'code' => 201,
  177. ]));
  178. }
  179. }else{
  180. exit(json_encode([
  181. 'message' => 'params key canot be null!',
  182. 'code' => 203,
  183. ]));
  184. }
  185. }
  186. private static function getSign($params, $appkey, $appSecret, $time)
  187. {
  188. $sign = '';
  189. if (!empty($params)) {
  190. ksort($params);
  191. $string = http_build_query($params);
  192. $result = md5($appkey . $string . $appSecret . $time);
  193. $sign = strtoupper($result);
  194. }
  195. return $sign;
  196. }
  197. private function checkSignature($params,$timestamp,$signature)
  198. {
  199. defined('APP_ID') or define("APP_ID", "disanbo");
  200. defined('APP_SECRET') or define("APP_SECRET", "di~sanbo1");
  201. $appkey = APP_ID;
  202. $appSecret = APP_SECRET;
  203. $sign= $this->getSign($params, $appkey, $appSecret, $timestamp);
  204. // var_dump($sign);die;
  205. if( $sign == $signature ){
  206. //do something
  207. return true;
  208. }else{
  209. return false;
  210. }
  211. }
  212. /* rabbitdata
  213. *
  214. *
  215. * */
  216. private function checkRabbitdata($rabbitdata)
  217. {
  218. //其他验证 dosomething
  219. if(!empty($rabbitdata)){
  220. return true;
  221. }else{
  222. exit(json_encode([
  223. 'message' => 'rabbitdata cannot be null!',
  224. 'code' => 202,
  225. ]));
  226. }
  227. }
  228. }