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

2021-03-04  本文已影响0人  DragonersLi

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

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了。
上一篇下一篇

猜你喜欢

热点阅读