123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- <?php
- /**
- * @Name
- * @Description
- * @Author 刘学玺
- * @Date 2024/3/25 17:00
- */
- namespace App\Http\Services\Frontend\Client\Auth;
- use App\Exceptions\ApiException;
- use App\Http\Services\Frontend\Client\Common\AuthService;
- use App\Http\Services\Frontend\Client\Common\SmsService;
- use App\Http\Services\Service;
- use App\Models\Member\User;
- use App\Models\WechatUser;
- use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
- use Illuminate\Http\JsonResponse;
- use Illuminate\Http\Response;
- use Illuminate\Support\Facades\Cache;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Str;
- use Overtrue\LaravelWeChat\EasyWeChat;
- class WechatAuthenticatedService extends Service
- {
- /**
- * @throws InvalidArgumentException
- */
- public function oauth($data): array
- {
- $wechat = EasyWeChat::officialAccount();
- $oauth = $wechat->getOAuth();
- $scopes = $data['scopes'] ?: 'snsapi_base';
- //callback_url 是授权回调的URL
- //生成完整的授权URL
- $redirectUrl = $oauth->scopes([$scopes])->redirect($data['redirect_url']);
- return ['redirectUrl' => $redirectUrl];
- }
- /**
- * @throws InvalidArgumentException
- */
- public function callback(array $params): array
- {
- $wechat = EasyWeChat::officialAccount();
- $oauth = $wechat->getOAuth();
- // 获取 OAuth 授权用户信息
- $wechat_user = $oauth->userFromCode($params['code']);
- //$wechat_user = $user->toArray();
- $data = [
- 'openid' => $wechat_user->getId() ?? $wechat_user->getTokenResponse()['openid'],
- 'bindUser' => true
- ];
- $avatar = $wechat_user->getAvatar();
- $avatar && ($data['avatar'] = $avatar);
- $nickname = $wechat_user->getNickname();
- $nickname && ($data['nickname'] = $nickname);
- $userIsExists = User::query()->where('openid', $data['openid'])->exists();
- if (!$userIsExists) {
- // $user_id = User::query()->create($data)->id;
- // $user = User::query()->find($user_id);
- $data['bindUser'] = false;
- }
- // $isExits = $this->hasOpenID($data['openid']);
- // 是否已存在
- // !$isExits && $this->create($data);
- // $wechatUser = WechatUser::query()->with('user.info')->where('openid', $data['openid'])->first();
- // return $this->success('', ['wechatUser' => $wechatUser->toArray()]);
- return $data;
- }
- private function hasOpenID($openId): bool
- {
- return false;
- // return WechatUser::query()->where('openid', $openId)->exists();
- }
- /**
- * @throws ApiException
- */
- public function bind(array $params): void
- {
- $mobile = $params['mobile'];
- $code = $params['code'];
- $openid = $params['open_id'];
- // 验证验证码
- $verifyCodeResult = (new SmsService())->verifyCode($mobile, $code);
- !$verifyCodeResult && self::error('验证码错误!', 400);
- // 获取微信信息
- // $data = [
- // 'openid' => $params['openid'],
- // 'avatar' => $params['avatar'],
- // 'nickname' => $params['nickname'],
- // ];
- $register_ip = request()->getClientIp();
- // 获取绑定用户
- User::query()->updateOrCreate(['openid' => $openid], ['openid' => $openid, 'mobile' => $mobile, 'register_ip' => $register_ip]);
- }
- /**
- * @throws ApiException
- */
- public function store($data): array
- {
- // 公众号OpenID
- $openID = $data['open_id'];
- $autoRegister = $data['auto_register'] ?? 0;
- $user = User::query()->where('openid', $openID)->first();
- if (!$user && $autoRegister) {
- // 获取微信信息
- // 创建用户信息
- $user_id = User::query()->create(['openid' => $openID])->id;
- $user = User::query()->find($user_id);
- }
- $token = (new AuthService)->store($user);
- return ['token' => $token];
- }
- public function create1($data): Response
- {
- // 判断验证码
- (new SmsService())->verify($data['mobile'], $data['code']);
- $where = ['mobile' => $data['mobile'], 'type' => 0];
- $exists = User::query()->where($where)->exists();
- if (!$exists) User::query()->create($where);
- // 绑定公众号
- $user = User::query()->where($where)->first();
- $user->open_id = $data['openid'];
- $user->save();
- return (new AuthService)->store($user);
- }
- // 发送短信
- public function send($data): Response
- {
- $mobile = $data['mobile'];
- $sms = new SmsService();
- return $sms->send($mobile, 0, 2);
- }
- /**
- * 公众号签名
- * @throws ApiException
- */
- public function getSignature(array $data): array
- {
- $wechat = EasyWeChat::officialAccount();
- $ticket = $wechat->getTicket();
- $jsapi_ticket = $ticket->getTicket();
- // 当前URL
- $url = request('url',request()->header('referer'));
- // 生成签名
- $nonceStr = 'xiaoding'.Str::random(20); // 请用随机算法生成
- $timestamp = time(); // 当前时间戳
- $signatureStr = "jsapi_ticket={$jsapi_ticket}&noncestr={$nonceStr}×tamp={$timestamp}&url={$url}";
- $signature = sha1($signatureStr);
- $wechatConfig = $wechat->getConfig();
- // 数据用于前端显示
- $signPackage = [
- "appId" => $wechatConfig['app_id'],
- "nonceStr" => $nonceStr,
- "timestamp" => $timestamp,
- "url" => $url,
- "signature" => $signature,
- "rawString" => $signatureStr
- ];
- // $sign = $this->makeSha1Sign($signData); // 生成微信签名
- //
- // $signData['signature'] = $sign;
- return $signPackage;
- //
- //
- // $access_token = $this->getAccessToken();
- //
- // // 这里的$token就是你在微信公众平台设置的Token
- // // 这里的$timestamp就是时间戳
- // // 这里的$nonce就是随机数
- // // 这里的$msg就是发送给微信服务器的数据
- //
- // // 将token、timestamp、nonce三个参数按字典序排序
- // $array = array($token, $timestamp, $nonce, $msg);
- // sort($array, SORT_STRING);
- //
- // // 将排序后的三个参数拼接成一个字符串
- // $str = implode($array);
- //
- // // 使用sha1算法计算出摘要
- // $signature = sha1($str);
- //
- // // 转换成小写
- // $signature = strtolower($signature);
- //
- // return $signature;
- }
- //生成 sha1 签名
- private function makeSha1Sign($array): string
- {
- //升序数组的键
- ksort($array);
- $params = urldecode(http_build_query($array));
- //字符串SHA1
- return sha1($params);
- }
- //获取微信access_token
- /**
- * @throws ApiException
- */
- private function getAccessToken()
- {
- $tokeUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . config('easywechat.official_account.default.app_id') . "&secret=" . config('easywechat.official_account.default.secret');
- $tokenResp = file_get_contents($tokeUrl);
- !$tokenResp && self::error('token 服务器返回失败');
- $tokenData = json_decode($tokenResp, true);
- if (!isset($tokenData['access_token'])) self::error($tokenData['errmsg']);
- return $tokenData['access_token'];
- }
- //获取微信ticket
- /**
- * @throws ApiException
- */
- private function getTicket($access_token)
- {
- $ticketUrl = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $access_token . '&type=jsapi';
- $ticketResp = file_get_contents($ticketUrl);
- if (!$ticketResp) return self::error('ticket 获取失败');
- $ticketData = json_decode($ticketResp, true);
- if (!isset($ticketData['ticket'])) return self::error('ticket 解析错误');
- $ticket = $ticketData['ticket'];
- cache::set('wechart_share_ticket', $ticket, 7200);
- return $ticket;
- }
- }
|