接口权限
-网页服务
-网页授权
-网页授权获取用户信息
-编辑【设置网页授权域名】
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&redirect_uri=https%3A%2F%2Fm.huanlvwuyou.cn%2Fapi%2Fwechat%2Fcallback&response_type=code&scope=snsapi_userinfo&state=dd241d598095a5ae6498e9d8b68e7ca0&connect_redirect=1#wechat_redirect'" />
<title>Redirecting to 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</title>
</head>
<body>
Redirecting to <a href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxcfa6c977f4c2f962&redirect_uri=https%3A%2F%2Fm.xxx.cn%2Fapi%2Fwechat%2Fcallback&response_type=code&scope=snsapi_userinfo&state=dd241d598095a5ae6498e9d8b68e7ca0&connect_redirect=1#wechat_redirect">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</a>.
</body>
</html>
上面html文件前端显示的是跳转微信客户端打开链接
正常到这步跳转的应该是url这里却显示html
打印要跳转的链接,结果为html文件 加send()和不加打印都是htmlcomposer 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了。
网友评论