微信公众号怎么授权给第三方?如何联系微信公众号第三方授权

微信开放平台第三方授权登录获取用户信息

背景:

2021-12-27 微信 cgi-bin/user/info 接口不再提供用户头像和昵称信息,大家无法在用户扫码通过关注事件无感知到拿到相关信息了;

按官方说法,获取用户头像昵称数据都需要用户前端网页授权,需要使用 sns/userinfo 接口;

补充:此方案针对的是公众号授权开放平台之后的,获取用户信息的流程;如果是独立的公众号或小程序,理论上和这个流程大体一致,但更为简单;如有疑问可以在评论留言。

方案流程如下:

如果是纯服务端开发,没有前端页面跳转,则需要有个跳转获取code的过程;

// 1.微信登录;第一次没有code,会自跳转生成一个code
public function wxLogin()
{
$appid = I('appid'); // 某一个公众号的appid
if (!isset($_GET['code'])) {
$this->getCode($appid);
}
$tokenData = $this->getComponentAccessToken($appid, $_GET['code']);
if (empty($tokenData['status']) {
echo '授权失败'
exit;
}
$userInfo = $this->getUserInfo($tokenData['data']['OPENid'], $tokenData['data']['access_token']);
return $userInfo;
}

// 自跳转过程
public function getCode($appid, $scope='snsapi_userinfo')
{
$request = array(
'appid' => $appid,
'redirect_uri' => get_request_scheme().$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'],
'response_type' => 'code',
'scope' => $scope,
'state' => 'state',
'component_appid' => C('APPID'), // 开放平台的appid
);
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?'.http_build_query($request).'#wechat_redirect';
header("location: {$url}");
exit;
}

// 2.获取该appid授权的开放平台的access_token
public function getComponentAccessToken($appid, $code): array
{
$url = "sns/oauth2/component/access_token";
$param = [
'appid' => $appid,
'code' => $code,
'grant_type' => 'authorization_code',
'component_appid' => C('APPID'), // 开放平台的appid
'component_access_token' => $this->componentToken(),
];

$fetchData = $this->curlGet($url . '?' . http_build_query($param));

if (empty($fetchData)) {
return ['status' => 0, 'msg' => '微信服务器登录失败', 'data' => []];
}

//错误返回 {"errcode":40029,"errmsg":"invalid code"}
//正确返回 {"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"oINQu5d6uAwEhIgFvpbah4atffbc","scope":"SCOPE"}
$fetchData = json_decode($fetchData, true);
if (isset($fetchData['errcode'])) {
return ['status' => 0, 'msg' => $fetchData['errcode'] . '-' . $fetchData['errmsg'], 'data' => $fetchData];
}

return ['status' => 1, 'msg' => '', 'data' => $fetchData];
}

// 3. 获取公众号用户信息
// https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
public function getUserInfo($openid, $access_token): array
{
$param = [
'access_token' => $access_token,
'openid' => $openid,
'lang'=>'zh_CN',
];

$url = "sns/userinfo";
//请求失败:{"errcode":40003,"errmsg":" invalid openid "}
//请求成功:{
// "openid": "OPENID",
// "nickname": NICKNAME,
// "sex": 1,
// "province":"PROVINCE",
// "city":"CITY",
// "country":"COUNTRY",
// "headimgurl":"https://thirdwx.qlogo.cn/mmopen/xxxxxxxbx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
// "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
// "unionid": "o6_bmasdasdsad6_xxxxxx"
//}
$fetchData = $this->curlGet($url . '?' . http_build_query($param));
if (empty($fetchData)) {
return ['status' => 0, 'msg' => '微信服务器获取用户信息失败', 'data' => []];
}

$fetchData = json_decode($fetchData, true);

if (isset($fetchData['errcode'])) {
return ['status' => 0, 'msg' => $fetchData['errcode'] . '-' . $fetchData['errmsg'], 'data' => $fetchData];
}

return ['status' => 1, 'msg' => '', 'data' => $fetchData];
}

public function curlGet($url, $headers = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$data = curl_exec($ch);
curl_close($ch);
return $data;
}

// 获取第三方平台component_access_token
// {"component_access_token":"8BINO1szMZtuJshySnl6TEMXkmSdM-E8le1yzC4U9tPmLUr2wLEUJCaL9QIxFPT_OcoXAkNDMpm0HuPJzFASitiS-Daskk1URPy7xaUe1yNCPu_73oVDyXYsqFg0zVmxXVVjAHATRR","expires_in":7200}
// 每个令牌是存在有效期(2小时)的,且令牌的调用不是无限制的,请第三方平台做好令牌的管理,在令牌快过期时(比如1小时50分)再进行刷新
public function componentToken() {
$redis = new Redis();
$componenttoken = $redis->get(C('CTKEY'));
if (!empty($componenttoken)) return $componenttoken;

// VTKEY 参考https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/Before_Develop/creat_token.html
// 需要在微信服务器推送的时候存起来; 在这里用上
$verifyticket = $redis->get(C('VTKEY'));
$params = array(
'component_appid' => C('APPID'),
'component_appsecret' => C('APPSECRET'),
'component_verify_ticket' => $verifyticket,
);
$ret = $this->curlGet('cgi-bin/component/api_component_token', $params);
$redis->set(C('CTKEY'), $ret['component_access_token'], C('CTTTL'));
return $ret['component_access_token'];
}

参考官方文档:https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/Before_Develop/Official_Accounts/official_account_website_authorization.html

本文来自从筠投稿,不代表胡巴网立场,如若转载,请注明出处:https://www.hu85.com/284070.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 xxxxx@qq.com 举报,一经查实,本站将立刻删除。