Correction status:qualified
Teacher's comments:
一、主题:
微信网页授权登陆的理解及实例。
二、微信网页授权步骤解析:
1.验证signature签名校验:将用户请求与微信api回调数据对比,一致则通过;
2.验证通过后,请求获取用户access_token,并缓存至文件中减少请求数据次数,此access_token在使用微信api功能时经常用到,是开发微信公众号功能的必备条件;
3.建立用户公众号菜单,使用微信官方文档提供的数据格式将菜单数据推送到微信菜单请求url,可使用http_Post()(curl)方法;
4.获取code,通过获取的code交换微信网页授权access_token,这里特别注意这个access_token与前面的access_token完全不一样,不要缓存。
5.获取到网页授权access_token后就可以使用access_token向微信api请求用户信息了,返回json数据。
<?php namespace app\index\model; use think\Model; use think\facade\Cache; class Wechat extends Model { // 微信signature签名校验 public function check() { // 将微信服务器的请求数据分别存为变量 $signature = input('get.signature'); $timestamp = input('get.timestamp'); $nonce = input('get.nonce'); $echostr = input('get.echostr'); // 在框架配置文件中设置微信的token,并读取 $token = config('app.wechattoken'); // 将获取的数据存到一个数组中 $tmpArr = array($timestamp, $nonce, $token); // 排序数据数组 sort($tmpArr, SORT_STRING); // 将排序后的数组数据拼接成一个字符串 $str = implode($tmpArr); // echo $str; exit; // 判断加密后的字符串与微信请求中的signature是否一致 if(sha1($str) != $signature) { return false; } return true; } // 获取校验access_token(区别于网页授权access_token) public function access_token($iscache = true) { // 如果某个参数使用较多,放到一个变量中,方便更改 $cache_key = 'access_token'; // 默认不用删除缓存 if(!$iscache) { Cache::rm($cache_key); } // 获取缓存中的access_token值 $access_token = Cache::get($cache_key); if($access_token && $iscache) { return $access_token; } // 将appid和appsecret(微信公众号中获取)的值保存至config/app.php中,并调取 $appid = config('app.appid'); $appsecret = config('app.appsecret'); // 拼接url $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='. $appid. '&secret='. $appsecret; // 获取access_token的值,返回一个json数据 $res = http_Get($url); // 将json数据转换成数组 $res = json_decode($res, true); // 如果没有拿到access_token的值,返回false if(!isset($res['access_token'])) { return false; } // 拿到数据后进行缓存,使用facade中的Cache Cache::set($cache_key, $res['access_token'], $res['expires_in']-300); return $res['access_token']; } // 换取网页授权access_token public function auth_access_token($code) { $appid = config('app.appid'); $appsecret = config('app.appsecret'); $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='. $appid. '&secret='. $appsecret. '&code='. $code. '&grant_type=authorization_code'; $res = http_Get($url); $res = json_decode($res, true); if(!isset($res['access_token'])) { return false; } return $res; } // 拉取用户信息 public function get_userinfo($auth_access_token, $openid) { $url = 'https://api.weixin.qq.com/sns/userinfo?access_token='. $auth_access_token. '&openid='. $openid. '&lang=zh_CN'; $res = http_Get($url); $res = json_decode($res, true); return $res; } }
点击 "运行实例" 按钮查看在线实例
<?php namespace app\index\controller; use think\Controller; class Wechat extends Controller { // 微信signature签名校验 public function __construct() { parent::__construct(); $this->model = model('Wechat'); } public function index() { $check = $this->model->check(); // 判断模型中返回值 if(!$check) { exit('signature error'); } exit(input('get.echostr')); } // 获取校验access_token(区别于网页授权access_token) public function get_access_token() { $access_token = $this->model->access_token(); return $access_token; } // 自定义菜单 // 1.必须是公众号; // 2.添加白名单。 public function custom_menu() { $access_token = $this->model->access_token(); if(!$access_token) { exit('无法获取access_token'); } // 菜单请求url拼接 $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token='. $access_token; // $url = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token='. $access_token; // 菜单数据:button一级菜单,sub_button二级菜单 $data = '{ "button":[ { "type":"view", "name":"百度搜索", "url":"https://www.baidu.com/" }, { "name":"测试菜单", "sub_button":[ { "type":"view", "name":"用户信息", "url":"http://269f571f.ngrok.io/index.php/index/wechat/auth" }, { "type":"view", "name":"用户地理位置", "url":"https://www.baidu.com/" } ] }, { "type":"view", "name":"赞一下", "url":"https://www.baidu.com/" } ] }'; // 使用公共函数http_Post()发送请求,需要带上参数 $res = http_Post($url, $data); // 打印返回码(查看是否成功) dump($res); } // 微信网页授权 public function auth() { // 如果正式公众号必须使用备案域名,并配置到公众号回调域名中 $redirect_uri = 'http://269f571f.ngrok.io/index.php/index/wechat/userinfo'; // 第一步:用户同意授权,获取code $url_code = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='. config('app.appid'). '&redirect_uri='. urlEncode($redirect_uri).'&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect'; // 获取$url的Loation请求头信息 header('Location:'. $url_code); } // 显示用户信息 public function userinfo() { // 获取code $code = input('get.code'); // 第二步:通过code换取网页授权access_token(注意这个和之前的普通access_token完全不一样) $res = $this->model->auth_access_token($code, false); $auth_access_token = $res['access_token']; $openid = $res['openid']; // 第三步:拉取用户信息(需要scope为snsapi_userinfo) $userinfo = $this->model->get_userinfo($auth_access_token, $openid); dump($userinfo); } }
点击 "运行实例" 按钮查看在线实例