diff --git a/app/controller/api/Wx.php b/app/controller/api/Wx.php deleted file mode 100644 index eb57764..0000000 --- a/app/controller/api/Wx.php +++ /dev/null @@ -1,47 +0,0 @@ -param(); - - $signature = $param['signature'] ?? '';// 签名 - $timestamp = $param['timestamp'] ?? '';// 时间戳 - $nonce = $param['nonce'] ?? '';// 随机数 - $echostr = $param['echostr'] ?? '0'; // 随机字符串 - - $checkRes = $this->checkSignature($signature,$timestamp,$nonce); - - $param['res_error'] = $checkRes; - - Log::write($param); - - echo $echostr;die; - } - - private function checkSignature($signature,$timestamp,$nonce):bool - { - $token = $this->token; - $tmpArr = array($token, $timestamp, $nonce); - sort($tmpArr, SORT_STRING); - $tmpStr = implode( $tmpArr ); - $tmpStr = sha1( $tmpStr ); - - if( $tmpStr == $signature ){ - return true; - }else{ - return false; - } - } -} \ No newline at end of file diff --git a/app/controller/wechat/Login.php b/app/controller/wechat/Login.php index deb689c..64317df 100644 --- a/app/controller/wechat/Login.php +++ b/app/controller/wechat/Login.php @@ -105,7 +105,7 @@ class Login extends Base } private function doLogin(string $openid, array $userDetail): Response { - $userInfo = (new WechatUser())->where('openid', $openid)->find(); + $userInfo = (new WechatUser())->openIdUserInfo($openid); if (empty($userInfo)) { $userInfo = WechatUser::create([ 'nickname' => $userDetail['nickname'], @@ -114,15 +114,19 @@ class Login extends Base 'unionid' => $userDetail['unionid'] ?? '', 'create_time' => time(), 'headimgurl' => $userDetail['head_img'], + 'last_login_time' => time() ]); + $data = (new WechatUser())->getUserInfo($userInfo['id']); } else { if (!$userInfo['status']) { return $this->buildFailed(ReturnCode::LOGIN_ERROR, '用户已被封禁,请联系管理员'); } + unset($userInfo['status']); + (new WechatUser())->addLoginTime($userInfo['id']); + $data = $userInfo; } - $data = $userInfo->toArray(); - unset($data['delete_time'],$data['status']); + $data['token'] = $this->signToken($data); return $this->buildSuccess($data, '登录成功'); } diff --git a/app/controller/wechat/Wechat.php b/app/controller/wechat/Wechat.php index 9ca1f7a..bb95312 100644 --- a/app/controller/wechat/Wechat.php +++ b/app/controller/wechat/Wechat.php @@ -3,8 +3,15 @@ namespace app\controller\wechat; +use app\model\WechatPucode; +use app\model\WechatUser; +use app\validate\WechatUser as WechatUserValidate; use app\service\wechat\WechatService; +use app\util\ReturnCode; +use think\exception\ValidateException; +use think\facade\Db; use think\Request; + class Wechat extends Base { @@ -15,17 +22,67 @@ class Wechat extends Base $signature = $param['signature'] ?? '';// 签名 $timestamp = $param['timestamp'] ?? '';// 时间戳 - $nonce = $param['nonce'] ?? '';// 随机数 - $echostr = $param['echostr'] ?? '0'; // 随机字符串 + $nonce = $param['nonce'] ?? ''; // 随机数 + $echostr = $param['echostr'] ?? '0'; // 随机字符串 - $checkRes = (new WechatService())->wechatChekToken($signature,$timestamp,$nonce); + $checkRes = (new WechatService())->wechatChekToken($signature, $timestamp, $nonce); $param['res_error'] = $checkRes; if ($checkRes) { - echo $echostr;die; + echo $echostr; + die; } return $this->buildFailed(400,'微信认证失败!'); } + + /** + * 用户添加手机号用户编号 + * @param Request $request + * @return \think\Response + */ + public function savePuCode(Request $request) + { + + $param = $request->param(); + + // 验证数据 + try { + validate(WechatUserValidate::class)->scene('savePuCode')->check($param); + } catch (ValidateException $e) { + return $this->buildFailed(ReturnCode::INVALID,$e->getMessage()); + } + + Db::startTrans(); + try { + + $mobile = $param['mobile']; + $pucode = $param['pucode']; + + $wechat_user_id = $request->wechat_user_id; + + $userData = ['phone' => $mobile]; + $WechatUser = WechatUser::update($userData,['id' => $wechat_user_id]); + if (!$WechatUser) { + throw new \Exception('添加失败'); + } + + $WechatPucode = WechatPucode::createPuCode($wechat_user_id,$pucode); + if (!$WechatPucode) { + throw new \Exception('添加失败'); + } + + Db::commit(); + + $data = $WechatUser->getUserInfo($wechat_user_id); + + $token = $this->signToken($data); + + return $this->buildSuccess(['token' => $token]); + } catch (\Exception $e) { + Db::rollback(); + return $this->buildFailed(ReturnCode::UPDATE_FAILED,$e->getMessage()); + } + } } \ No newline at end of file diff --git a/app/middleware/WechatAuth.php b/app/middleware/WechatAuth.php new file mode 100644 index 0000000..6e16d5d --- /dev/null +++ b/app/middleware/WechatAuth.php @@ -0,0 +1,78 @@ +header('token', ''); + if ($token) { + $userInfo = $this->checkToken($token); + if ($userInfo['code'] == 2) { + return json([ + 'code' => ReturnCode::AUTH_ERROR, + 'msg' => $userInfo['msg'], + 'data' => [] + ])->header($header); + } else { + $request->wechat_user = $userInfo['data']; + $request->wechat_user_id = $userInfo['data']['id']; + } + + return $next($request); + } else { + return json([ + 'code' => ReturnCode::AUTH_ERROR, + 'msg' => '缺少token', + 'data' => [] + ])->header($header); + } + } + + + + /** + * 验证token + * @param $token + * @return array|int[] + */ + private function checkToken($token): array + { + $key = config('jwt.key'); + $status = array("code" => 2); + try { + JWT::$leeway = 60; //当前时间减去60,把时间留点余地 + $decoded = JWT::decode($token, new Key($key, 'HS384')); //同上的方式,这里要和签发的时候对应 + $arr = (array)$decoded; + $res['code'] = 200; + $res['data'] = $arr['data']; + $res['data'] = json_decode(json_encode($res['data']), true);//将stdObj类型转换为array + return $res; + + } catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确 + $status['msg'] = "签名不正确"; + return $status; + } catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用 + $status['msg'] = "token失效"; + return $status; + } catch (\Firebase\JWT\ExpiredException $e) { // token过期 + $status['msg'] = "token失效"; + return $status; + } catch (\Exception $e) { //其他错误 + $status['msg'] = "未知错误"; + return $status; + } + } +} \ No newline at end of file diff --git a/app/model/WechatPucode.php b/app/model/WechatPucode.php new file mode 100644 index 0000000..b87bd3b --- /dev/null +++ b/app/model/WechatPucode.php @@ -0,0 +1,35 @@ + $user_id, + 'pucode' => $pucode + ]; + + $query = self::where($data)->find(); + if ($query) { + return $query; + } + + $data['create_time'] = time(); + + return self::create($data); + } +} \ No newline at end of file diff --git a/app/model/WechatUser.php b/app/model/WechatUser.php index 2e4eb6a..5dee9b0 100644 --- a/app/model/WechatUser.php +++ b/app/model/WechatUser.php @@ -5,6 +5,26 @@ namespace app\model; class WechatUser extends Base { + /** + * 获取微信用户信息 + * @param $id + * @return WechatUser|array|mixed|\think\Model|null + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function getUserInfo($id) + { + $field = 'id,openid,nickname,headimgurl,phone,unionid'; + return $this->where('id',$id)->field($field)->find(); + } + public function openIdUserInfo($openid){ + $field = 'id,openid,nickname,headimgurl,phone,unionid,status'; + return $this->where('openid',$openid)->field($field)->find(); + } + public function addLoginTime($id) { + $this->where('id',$id)->save(['last_login_time' => time()]); + } } \ No newline at end of file diff --git a/app/validate/WechatUser.php b/app/validate/WechatUser.php new file mode 100644 index 0000000..b755e29 --- /dev/null +++ b/app/validate/WechatUser.php @@ -0,0 +1,36 @@ + 'require|mobile', + 'pucode|用户编号' => 'require|number', + ]; + + /** + * 提示消息. + */ + protected $message = [ + ]; + + /** + * 字段描述. + */ + protected $field = [ + ]; + + /** + * 验证场景. + */ + protected $scene = [ + 'savePuCode' => ['mobile', 'pucode'] + ]; + +} \ No newline at end of file