博客列表 >微信公众号实战:网页授权登陆--20180603-9:40发布(0601作业)

微信公众号实战:网页授权登陆--20180603-9:40发布(0601作业)

lilove的博客
lilove的博客原创
2018年06月06日 19:22:021259浏览

一、主题:

微信网页授权登陆的理解及实例。

二、微信网页授权步骤解析:

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数据。

模型(Wechat.php)实例

<?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;
    }
}

运行实例 »

点击 "运行实例" 按钮查看在线实例

控制器(Wechat.php)实例

<?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);
	}

}

运行实例 »

点击 "运行实例" 按钮查看在线实例


声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议