美文网首页
微信公众号easywechat授权问题踩填🕳笔记!

微信公众号easywechat授权问题踩填🕳笔记!

作者: DragonersLi | 来源:发表于2021-03-04 11:32 被阅读0次

    接口权限-网页服务-网页授权-网页授权获取用户信息-编辑【设置网页授权域名】

    easywechat公众号接自动授权问题:
    在之前项目接入的自动回复基础上继续开发授权。
    项目thinkphp6框架,php7.4,nginx1.18 
    easywechat版本 :"overtrue/wechat": "^4.2",#4.2.33
    
    一开始错误思路:
    用户关注公众号时event是可以获取openid的,
    如果我把这个openid存储在session或者cookie在用户注册或者登陆时候,直接和用户绑定不久可以了么?
    然后踩坑了:
    session和cookie始终无法保存openid,而cache却是可以的。
    然后就各种找原因,用原始写法,不用tp封装的方法,还是不行。
    最后只好放弃,看手册怎样网页授权了。
    
    关注和取消关注event事件 踩坑:最后跳转地址打印出来一直是空的
    公众号h5登陆,用的tp6框架。return  $oauth->redirect()->send();后就没反应了,是什么原因呢?
    
    $oauth->redirect()
    打印出来:{"headers":{}}
    
    $redirectUrl = $app->oauth->scopes(['snsapi_userinfo'])->redirect();
    打印出来: {"headers":{}}
    
    手册发起授权代码demo,使用后终于打印出来东西了,可是并不是要的url而是html
    HTTP/1.0 302 Found
    Cache-Control: no-cache, private
    Date:          Fri, 27 Nov 2020 06:43:37 GMT
    Location:      https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxcfa6c977f4c2f962&redirect_uri=https%3A%2F%2Fm.huanlvwuyou.cn%2Fapi%2Fwechat%2Fcallback&response_type=code&scope=snsapi_userinfo&state=dd241d598095a5ae6498e9d8b68e7ca0&connect_redirect=1#wechat_redirect
    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <meta http-equiv="refresh" content="0;url='https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxcfa6c977f4c2f962&amp;redirect_uri=https%3A%2F%2Fm.huanlvwuyou.cn%2Fapi%2Fwechat%2Fcallback&amp;response_type=code&amp;scope=snsapi_userinfo&amp;state=dd241d598095a5ae6498e9d8b68e7ca0&amp;connect_redirect=1#wechat_redirect'" />
    
            <title>Redirecting to https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxcfa6c977f4c2f962&amp;redirect_uri=https%3A%2F%2Fm.huanlvwuyou.cn%2Fapi%2Fwechat%2Fcallback&amp;response_type=code&amp;scope=snsapi_userinfo&amp;state=dd241d598095a5ae6498e9d8b68e7ca0&amp;connect_redirect=1#wechat_redirect</title>
        </head>
        <body>
            Redirecting to <a href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxcfa6c977f4c2f962&amp;redirect_uri=https%3A%2F%2Fm.xxx.cn%2Fapi%2Fwechat%2Fcallback&amp;response_type=code&amp;scope=snsapi_userinfo&amp;state=dd241d598095a5ae6498e9d8b68e7ca0&amp;connect_redirect=1#wechat_redirect">https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxcfa6c977f4c2f962&amp;redirect_uri=https%3A%2F%2Fm.huanlvwuyou.cn%2Fapi%2Fwechat%2Fcallback&amp;response_type=code&amp;scope=snsapi_userinfo&amp;state=dd241d598095a5ae6498e9d8b68e7ca0&amp;connect_redirect=1#wechat_redirect</a>.
        </body>
    </html>
    
    上面html文件前端显示的是跳转微信客户端打开链接
    正常到这步跳转的应该是url这里却显示html
    打印要跳转的链接,结果为html文件 加send()和不加打印都是html
    composer require overtrue/wechat --with-all-dependencies
    composer更新至最新版本,终于上面打印的不再是html而是url链接了 header跳转后,exit退出一下
    使用旧版本的方法,用的却是刚更新的最新版本的easywechat,难怪一直有问题
    报错没有这个方法:回调函数里获取不到用户信息
    更新easywechat到最新版本,当然也要看最新版本的文档,使用最新版本里的方法了!(lll¬ω¬)
    掉进坑里爬不上来了,终于忍不住花了10元巨款加了easywechat官方群,然后被作者一顿虐,最后静下心来想解决办法,一步步终于走通了流程。还是非常感谢的,虽然被虐的体无完肤。
    被虐一 被虐二

    经历了前面各种踩坑,终于回到正轨:

    image.png
    微信配置文件
    <?php
    
    return [
        /**
         * 账号基本信息,请从微信公众平台/开放平台获取
         */
        'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', 'xxx'),         // AppID
        'secret' => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', 'xx'),    // AppSecret
        'token' => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', 'xxx'),           // Token
        'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', 'xxx'), // EncodingAESKey
    
        /**
         * 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
         * 使用自定义类名时,构造函数将会接收一个 `EasyWeChat\Kernel\Http\Response` 实例
         */
         'response_type' => 'array',
    
        /**
         * 日志配置
         *
         * level: 日志级别, 可选为:
         *         debug/info/notice/warning/error/critical/alert/emergency
         * path:日志文件位置(绝对路径!!!),要求可写权限
         */
        'log' => [
            'default' => 'dev', // 默认使用的 channel,生产环境可以改为下面的 prod
            'channels' => [
                // 测试环境
                'dev' => [
                    'driver' => 'single',
                    'path' => app()->getRuntimePath() .'api'.DIRECTORY_SEPARATOR.'log'.DIRECTORY_SEPARATOR.date('Ymd').DIRECTORY_SEPARATOR.'easywechat.log',
                    'level' => 'debug',
                ],
                // 生产环境
                'prod' => [
                    'driver' => 'daily',
                    'path' =>  app()->getRuntimePath()  .'api'.DIRECTORY_SEPARATOR.'log'.DIRECTORY_SEPARATOR.date('Ymd').DIRECTORY_SEPARATOR.'easywechat.log',
                    'level' => 'info',
                ],
            ],
        ],
    
        /**
         * 接口请求相关配置,超时时间等,具体可用参数请参考:
         * http://docs.guzzlephp.org/en/stable/request-config.html
         *
         * - retries: 重试次数,默认 1,指定当 http 请求失败时重试的次数。
         * - retry_delay: 重试延迟间隔(单位:ms),默认 500
         * - log_template: 指定 HTTP 日志模板,请参考:https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php
         */
        'http' => [
            'max_retries' => 1,
            'retry_delay' => 500,
            'timeout' => 5.0,
            // 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri
        ],
    
        /**
         * OAuth 配置
         *
         * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
         * callback:OAuth授权完成后的回调页地址
         */
        'oauth' => [
            'scopes'   => ['snsapi_userinfo'],
            'callback' => config('system.api.url').'/api/wechat/callback',
        ],
    ];
    
    回调方法
    use EasyWeChat\Factory;
    
        public function __construct()
        {
            $this->app = Factory::officialAccount(config('wechat'));
           
        }
        /**
         * 回调页面
         * 接收微信返回的code,然后根据code获取微信授权的用户信息
         * 判断数据库微信表是否存在该openid,不存在则插入
         * 把微信信息存入session或者cookie,跳转授权前的页面
         * $code 微信授权的code
         */
        public function callback($code = ''){
            dlog('wx_callback',"--{$code}--");
            $user = $this->app->oauth->userFromCode($code);// 获取 OAuth 授权结果用户信息
       
            dlog('wx_callback',$data);
            $wechat_user = UserWeixin::where(['id'=>$user->id])->find();
            if(empty($wechat_user)){
                $res = UserWeixin::insert($data); 
            }
            dlog('wx_callback',json_encode($wechat_user));
            session('wechat_user',json_encode($user));
            $targetUrl = empty(session('target_url')) ? '/' : session('target_url');
            header('Location:'. $targetUrl);
    
        }
    
    
    中间件或者登陆注册需要授权页面的方法,先从session获取微信用户信息,不存在则跳转微信去获取code,然后把当前页面url存进session,授权完成再回来。
            if(strpos(request()->header('user-agent'), 'MicroMessenger')){//微信登陆
                dlog('wx_base','--微信登陆start--'.json_encode(session('wechat_user')));
                $app = Factory::officialAccount(config('wechat'));
                if (session('wechat_user') == null) {//如果获取不到微信信息
                    $target_url = request()->server('HTTP_REFERER') ?? config('system.api.url');
                    session('target_url',$target_url);//h5首页
                    $redirectUrl = $app->oauth->scopes(['snsapi_userinfo'])->redirect();
                    dlog('wx_base',$redirectUrl);
                }
               
            }
            dlog('wx_base','--微信登陆end--');
    
    
    登陆或者注册方法里每次登陆或注册先session拿存储的微信信息,去更新当前用户。
                $wechat_user = json_decode(session('wechat_user'));
                dlog('wx_login',session('wechat_user'));
                if($wechat_user){
                    UserWeixin::where(['id'=>$wechat_user->id])->update(['uid'=>$uid,'update_time'=>time()]);
                }
    

    跨域问题解决:

    $redirectUrl=https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI
    &response_type=code&scope=SCOPE&state=STATE#wechat_redirect
    
    就像 $redirectUrl只靠打印结果为空,最后不为空也不是html,是url链接为何还是跳不过去?
    用微信真机调试没报错信息,靠猜完全没头绪。 而使用微信开发者工具就方便很多了。
    `开发者工具`、`web开发者工具`、`绑定开发者账号`。然后输入要调试的页面就可以发现是跨域了,所以跳不过去。
    解决微信公众号授权跨域问题:
    用户进来,先 redirectUrl去微信授权拿到code然后去callback,回调里获取用户微信信息。
    在微信拿到code去回调方法的时候微信开发者工具上提示跨域了。
    拿到这个redirectUrl后和前端配合,前端跳转这个地址就ok了。
    

    相关文章

      网友评论

          本文标题:微信公众号easywechat授权问题踩填🕳笔记!

          本文链接:https://www.haomeiwen.com/subject/gzimrxtx.html