123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- <?php
- namespace app\admin\library;
- use app\common\library\Rabbitmq;
- use app\common\library\Redis;
- use app\common\library\WeChatObject;
- use app\main\service\WeChatAdService;
- use GuzzleHttp\Client;
- use Symfony\Component\Cache\Simple\RedisCache;
- use EasyWeChat\Factory;
- use think\Config;
- use think\Log;
- class AbWeChatAuthorization{
- protected $platform;
- protected $adminConfig;
- protected $weChat;
- public function __construct($platform_id,$channel_id){
- if(!$platform_id || !$channel_id){
- throw new \Exception('Platform_id OR Channel_id 为空');
- }
- //获取平台信息
- if(!$this->platform = model('Platform')->where(['id'=>$platform_id])->find()){
- throw new \Exception('获取平台信息失败');
- }
- Log::info(sprintf('微信授权: platform_id:%d channel_id:%d 取得平台信息',$platform_id,$channel_id));
- //获取渠道信息
- if(!$this->adminConfig = model('AdminConfig')->where(['admin_id'=>$channel_id])->find()){
- throw new \Exception('获取用户信息失败');
- }
- Log::info(sprintf('微信授权: platform_id:%d channel_id:%d 取得渠道信息',$platform_id,$channel_id));
- $wechatObj = new WeChatObject($this->adminConfig);
- $this->weChat = $wechatObj->getPlatform($platform_id);
- }
- /**
- * 授权处理
- * @param bool $isUpdate 是否是更新权限
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function authorization($isUpdate = false){
- // 使用授权码换取接口调用凭据和授权信息
- $auth = $this->weChat->handleAuthorize();
- // 检查当前授权的公众号与历史授权公众号是否一致
- $existsAppID = model('WechatAb')->where('appid',$auth['authorization_info']['authorizer_appid'])->where('admin_id','neq',$this->adminConfig->admin_id)->find();
- if($existsAppID){
- //更新平台用户refreshToken信息
- $this->updateUserRefrshToken($this->platform->id,$auth['authorization_info']['authorizer_refresh_token'],$existsAppID['admin_id'], $auth['authorization_info']['authorizer_appid']);
- throw new \Exception('一个服务号只能绑定一个账号!');
- }
- // 获取授权方的帐号基本信息
- $authInfo = $this->weChat->getAuthorizer($auth['authorization_info']['authorizer_appid']);
- Log::info(sprintf('Ab微信授权: platform_id:%d channel_id:%d 微信授权检测通过',$this->platform['id'],$this->adminConfig['admin_id']));
- //检测权限
- $this->checkWeChatAuth($authInfo);
- //添加微信AD数据源
- $data['appid'] = $auth['authorization_info']['authorizer_appid'];
- $wx_ad_source_id = WeChatAdService::instance()->createWxAdSourceId($data['appid'], $this->platform->id, $auth['authorization_info']['authorizer_refresh_token']);
- Log::info("数据AD:". $wx_ad_source_id);
- if (!$wx_ad_source_id) {
- throw new \Exception('Ab微信授权失败');
- }
- $data['wx_ad_source_id'] = $wx_ad_source_id;
- $data['admin_id'] = $this->adminConfig->admin_id;
- $data['platform_id'] = $this->platform->id;
- $data['refresh_token'] = $auth['authorization_info']['authorizer_refresh_token'];
- $data['json'] = json_encode($authInfo, 256);
- $data['createtime'] = time();
- $data['updatetime'] = time();
- Log::info(sprintf('Ab微信授权: platform_id:%d channel_id:%d 微信基本信息更新完成',$this->platform['id'],$this->adminConfig['admin_id']));
- if (!model('WechatAb')->allowField(true)->save($data)) {
- throw new \Exception('Ab更新授权信息失败');
- }
- //清除缓存
- $redis = Redis::instance();
- $redis->del('AA:' . $auth['authorization_info']['authorizer_appid']);
- }
- /**
- * 更新用户RefrshToken
- * @param $platform_id
- * @param $refresh_token
- * @param $admin_id
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- * @throws \Exception
- */
- private function updateUserRefrshToken($platform_id,$refresh_token,$admin_id = null, $appid){
- //更新ptoken信息
- $ptoken_map = ['admin_id'=>$this->adminConfig->admin_id,'platform_id'=>$platform_id, 'appid' => $appid];
- if($admin_id){
- $ptoken_map['admin_id'] = $admin_id;
- }
- if($ptoken = model('WechatAb')->where($ptoken_map)->find()){
- if(false === model('WechatAb')->where($ptoken_map)->update(['refresh_token'=>$refresh_token,'updatetime'=>time()])){
- throw new \Exception('Ab更新RefrshToken失败');
- }
- }
- Log::info(sprintf('Ab微信授权: platform_id:%d channel_id:%d 微信PTOKEN更新完成',$this->platform['id'],$this->adminConfig['admin_id']));
- }
- /**
- * 检测权限
- * @param $authUser
- * @throws \Exception
- */
- private function checkWeChatAuth($authUser){
- if (!isset($authUser['authorizer_info']['service_type_info']['id'])) {
- throw new \Exception('Ab获取授权信息失败,请重新扫码授权');
- }
- if ($authUser['authorizer_info']['service_type_info']['id'] != 2) {
- throw new \Exception('Ab当前授权公众号类型非服务号,请使用服务号进行扫码');
- }
- if ($authUser['authorizer_info']['verify_type_info']['id'] == -1) {
- throw new \Exception('Ab当前授权服务号未认证,请使用认证服务号进行扫码');
- }
- $authList = array_column(array_column($authUser['authorization_info']['func_info'], 'funcscope_category'), 'id');
- if(empty($authList)){
- throw new \Exception('Ab获取授权信息失败');
- }
- if(!in_array(1,$authList)){
- throw new \Exception('Ab必须授予-消息管理权限');
- }
- if(!in_array(15,$authList)){
- throw new \Exception('Ab必须授予-自定义菜单权限');
- }
- if(!in_array(4,$authList)){
- throw new \Exception('Ab必须授予-网页服务权限');
- }
- if(!in_array(2,$authList)){
- throw new \Exception('Ab必须授予-用户管理权限');
- }
- if(!in_array(3,$authList)){
- throw new \Exception('Ab必须授予-帐号服务权限');
- }
- if(!in_array(11,$authList)){
- throw new \Exception('Ab必须授予-素材管理权限');
- }
- if(!in_array(23,$authList)){
- throw new \Exception('Ab必须授予-广告管理权限');
- }
- }
- }
|