首页 课程中心 问答&分享 读书 公众号框架 HUI H.JS 开放源 登录 & 注册
 《微信公众号开发权威教程》

如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。


关于网页授权回调域名的说明

1、在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的开发者中心页配置授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头;

2、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com无法进行OAuth2.0鉴权。


关于网页授权的两种scope的区别说明

1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)

2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。


关于网页授权access_token和普通access_token的区别

1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;

2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。


网页授权流程分为四步:

1、引导用户进入授权页面同意授权,获取code

2、通过code换取网页授权access_token(与基础支持中的access_token不同)

3、如果需要,开发者可以刷新网页授权access_token,避免过期

4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)


演示文件结构

|_ login.php //检查用户是否登录 登录则显示登录信息 否则跳转到微信登录
|_ wxLogin/ 文件夹用于存储核心文件
    |_ config.php //用于定义appId redirect_uri等信息的核心配置文件
    |_ index.php //做为微信登录业务的核心文件
    |_ callback.php //微信登录成功后返回的文件,用于完成session或cookie信息的整理和记录。


实现步骤及演示代码


1、编写login.php

<?php
session_start();
if(empty($_SESSION['uid'])){
    header('location:wxLogin/index.php'); exit();
}else{
?>
<p>您已经登录!</p>
<p><img src="<?php echo $_SESSION['uface']; ?>" width="120" /><p>
<p>您的称呼: <?php echo $_SESSION['uname']; ?></p>
<?php }?>


2、编写config.php

<?php
//开启session
session_start();
//appid
define('appID'           ,   'wxecbdf50f2ffea20f');
//appsecret
define('appsecret'       ,   'eb2e237b0ed8624d4fd87a718ae2285b');
//微信登录成功返回的页面(回调页面)
define('BACKURL'         ,   'http://wx.hcoder.net/wxLogin/callback.php');
//微信登录所需的access_token信息存放文件位置
define('TOKEN_FILE'      ,    'access_token.json');


3、编写index.php

<?php
include 'config.php';
//设置state 一个随机码并使用session记录
$_SESSION['state'] = md5(rand(111111, 99999999));
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.appID.'&redirect_uri='.BACKURL.'&response_type=code&scope=snsapi_userinfo&state='.$_SESSION['state'].'#wechat_redirect';
//跳转即可
header('location:'.$url);
exit();


4、测试效果

使用手机微信或者电脑微信访问 login.php


5、完成callback.php回调页面代码的编写

<?php
include 'config.php';
//判断state是否正确
if(empty($_GET['state'])){exit('参数错误,请重新登录');}
if($_GET['state'] != $_SESSION['state']){exit('<script>alert("参数错误!"); location.href="../login.php";</script>');}
//检查用户是否同意授权
if(empty($_GET['code'])){exit('<script>alert("您没有同意授权!"); location.href="../login.php";</script>');}
/*
 * 通过code换取网页授权access_token
 * https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
 */
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.appID.
'&secret='.appsecret.
'&code='.$_GET['code'].
'&grant_type=authorization_code';
//通过curl获取access_token
$res  = myCurl($url);
/*
 * 正确返回
 * { "access_token":"ACCESS_TOKEN","expires_in":7200, "refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE" } 
 * 错误返回
 * {"errcode":40029,"errmsg":"invalid code"}
 */

//将json信息转换为数组
$info = json_decode($res, true);
//判断是否成功
if(empty($info['access_token'])){exit('参数错误,请重新登录...');}

/* 获取用户信息 
 * 请求地址: 
 * https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN 
 * 正确时返回的JSON数据包如下:
 * openid 用户的唯一标识 
 * nickname 用户昵称
 * 其他相信查看手册
 * 错误时微信会返回JSON数据包如下(示例为openid无效):
 * {"errcode":40003,"errmsg":" invalid openid "} 
*/
$url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$info['access_token'].'&openid='.$info['openid'].'&lang=zh_CN';
$res  = myCurl($url);
//将json信息转换为数组
$user = json_decode($res, true);
if(!empty($user['errcode'])){exit('参数错误,请重新登录...');}
//注册session 并返回登录页面
$_SESSION['uid']     = $user['openid'];
$_SESSION['uface']   = $user['headimgurl'];
$_SESSION['uname']   = $user['nickname'];
header('location:../login.php');

function myCurl($url, $type = 'GET', $data = null){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL            , $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER , true);
if($type != 'GET'){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER , false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST , false);
curl_setopt($curl, CURLOPT_ENCODING       , 'gzip,deflate');
$res  = curl_exec($curl);
curl_close($curl);
return $res;
}


最终演示效果


来着作者的鼓励:

有点麻烦,有点难! 不过经过努力是一定可以实现的!

书籍目录  (请点击阅读)