微信开放平台官方网站(微信开放平台第三方授权登录获取用户信息)

背景:

2021-12-27微信cgi-bin/user/info界面不再提供用户的图片和昵称信息,所以我们无法通过关注用户扫码时的事件来获取相关信息。

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


补充:此方案针对微信官方账号授权开放平台后获取用户信息的过程;如果是独立的微信官方账号或者小程序,理论上基本和这个流程一样,只是更简单一些;如果你有任何问题,请在评论中留言。

微信开放平台


该方案如下:

如果是纯服务器端开发,没有前端页面跳转,需要有一个跳转过程来获取代码;

// 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']; }


// 1.微信登录;第一次没有代码,一个代码 公共函数wxlogin() { $ appid = I(& # 39;appid & # 39);//某微信官方账号的AppID if(!isset($ _ GET[& # 39;代码& # 39;])){ $ this-& gt;getCode($ appid); } $ token data = $ this-& gt;getComponentAccessToken($appid,$ _ GET[& # 39;代码& # 39;]); if(empty($token data[& # 39;地位& # 39;]){ echo & # 39;授权失败& # 39; 退出; } $ userInfo = $ this-& gt;get userinfo($token data[& # 39;数据& # 39;]['openid & # 39],$ token data[& # 39;数据& # 39;]['访问令牌& # 39;]); return $ userInfo; } /自跳转进程 公共函数getcode ($ appid,$ scope = & # 39snsapi _ userinfo & # 39) { $ request = array( & # 39;appid & # 39= & gt$appid, & # 39;redirect _ uri & # 39= & gtget_request_scheme()。$ _服务器[& # 39;HTTP _ HOST & # 39].$ _服务器[& # 39;请求_ URI & # 39;], & # 39;响应类型& # 39;= & gt'代码& # 39;, & # 39;范围& # 39;= & gt$scope, & # 39;国家& # 39;= & gt'国家& # 39;, & # 39;component _ appid & # 39= & gtc(& # 39;APPID & # 39),//开放平台的AppID ); $ URL = & # 39;https://open.weixin.qq.com/connect/oauth2/authorize? & # 39;。http_build_query($request)。'#微信_重定向& # 39;; 标题(& # 34;位置:{ $ url } & # 34); 退出; } /2。获取access _ token 公共函数getcomponentaccesstoken ($ appid,$ code):array { $ SNS/oauth 2/component/access _ token & # 34;; $ param =[ & # 39;appid & # 39= & gt$appid, & # 39;代码& # 39;= & gt$code, & # 39;grant _ type & # 39= & gt'授权_代码& # 39;, & # 39;component _ appid & # 39= & gtc(& # 39;APPID & # 39),//开放平台的AppID & # 39;组件访问令牌& # 39;= & gt$ this-& gt;componentToken(), ]; $ fetch data = $ this-& gt;curl get($URL。'?'。http _ build _ query($ param)); if(empty($ fetch data)){ return[& # 39;地位& # 39;= & gt0, 'msg & # 39= & gt'微信服务器登录失败& # 39;, '数据& # 39;= & gt[]]; } //返回错误{ & # 34;错误代码& # 34;:40029,"errmsg & # 34:"无效代码& # 34;} //正确返回{ & # 34;访问令牌& # 34;:"访问令牌& # 34;,"expires _ in & # 34:7200,"刷新_令牌& # 34;:"刷新_令牌& # 34;,"openid & # 34:"oinqu 5d 6 uawehigfvpbah 4 atffbc & # 34;,"范围& # 34;:"范围& # 34;} $ fetch data = JSON _ decode($ fetch data,true); if(isset($ fetch data[& # 39;错误代码& # 39;])){ return[& # 39;地位& # 39;= & gt0, 'msg & # 39= & gt$ fetch data[& # 39;错误代码& # 39;] .'-'。$ fetch data[& # 39;errmsg & # 39], '数据& # 39;= & gt$ fetch data]; } return[& # 39;地位& # 39;= & gt1, 'msg & # 39= & gt'', '数据& # 39;= & gt$ fetch data]; } /3。获取微信官方账号中的用户信息 //https://developers . weixin . QQ . com/doc/offi account/OA _ web _ apps/we chat _ web公共函数getUserInfo($openid,$ access _ token):array { $ param = & # 39;访问令牌& # 39;= & gt$access_token, & # 39;openid & # 39= & gt$openid, & # 39;郎& # 39;= & gt'zh _ CN & # 39, ]; $ URL = & # 34;社交网站/用户信息& # 34;; //请求失败:{ & # 34;错误代码& # 34;:40003,"errmsg & # 34:"无效的openid & # 34} //请求成功:{ /& # 34;openid & # 34: "OPENID & # 34, //& # 34;昵称& # 34;:昵称, //& # 34;性& # 34;:1, //& # 34;省& # 34;:"省& # 34;, //& # 34;城市& # 34;:"城市& # 34;, //& # 34;国家& # 34;:"国家& # 34;, //& # 34;headimgurl & # 34:"https://thirdwx . qlogo . cn/mmopen/xxxxxxxbx 6 iafqac 56 vxls ufpb 6n 5 wksyvy 0 chqkkiajsgq 1 dzutogvllrhjberqq 4 emsv 84 eavhiaiceqxibjxcfhe/46 & # 34;, //& # 34;特权& # 34;:[ "特权1 & # 34;"特权2 & # 34;], //& # 34;unionid & # 34: "o6 _ bmasdasdsad6 _ xxxxxx & # 34 //} $ fetch data = $ this-& gt;curl get($URL。'?'。http _ build _ query($ param)); if(empty($ fetch data)){ return[& # 39;地位& # 39;= & gt0, 'msg & # 39= & gt'微信服务器获取用户信息失败& # 39;, '数据& # 39;= & gt[]]; } $ fetch data = JSON _ decode($ fetch data,true); if(isset($ fetch data[& # 39;错误代码& # 39;])){ return[& # 39;地位& # 39;= & gt0, 'msg & # 39= & gt$ fetch data[& # 39;错误代码& # 39;] .'-'。$ fetch data[& # 39;errmsg & # 39], '数据& # 39;= & gt$ fetch data]; } return[& # 39;地位& # 39;= & gt1, 'msg & # 39= & gt'', '数据& # 39;= & gt$ fetch data]; } 公共函数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); 返回$ data } //获取第三方平台component _ access _ token /{ & # 34;组件访问令牌& # 34;:"8 bino 1 szmztujshysn 16 temxkmsdm-e 8 le 1 yzc4 u 9 TPM Lu 2 leujcal 9 qixfpt _ ocoxakndpmp 0 hupjzfasitis-das kk 1 urpy 7 chaue1 yncpu _ 73 ovdyxysysqfg 0 zvmxxvjahatrr & # 34;,"expires _ in & # 34:7200} //每个代币都有有效期(2小时),代币的调用不是无限的。请第三方平台管理好令牌,刷新 公共函数组件令牌(){ $ redis = new redis( $ component token = $ redis-& gt;get(C(& # 39;CTKEY & # 39)); 如果(!empty($componenttoken))返回$ component token; /vtkey指https://developers.weixin.qq.com/doc/oplatform/third-party _平台/2.0/API/before _ develop/creat _ token.html //需要在使用中 $ verify ticket = $ redis-& gt;get(C(& # 39;VTKEY & # 39)); $ params = array( & # 39;component _ appid & # 39= & gtc(& # 39;APPID & # 39), & # 39;component _ appsecret & # 39= & gtc(& # 39;APPSECRET & # 39), & # 39;component _ verify _ ticket & # 39= & gt$verifyticket, ); $ ret = $ this-& gt;curl get(& # 39;CGI-bin/component/API _ component _ token & # 39;,$ params); $ redis-& gt;设置(C(& # 39;CTKEY & # 39),$ ret[& # 39;组件访问令牌& # 39;],C(& # 39;CTTTL & # 39)); ret $ ret[& # 39;组件访问令牌& # 39;]; }

官方文档:https://developers.weixin.qq.com/doc/oplatform/third-party _平台/2.0/API/before _开发/官方_账户/官方_账户_网站_ authorization.html。

您可以还会对下面的文章感兴趣

使用微信扫描二维码后

点击右上角发送给好友