热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

微信开发之网页授权获取用户信息(二)

本文给大家阐述的微信开发基于yii2.0框架,对微信开发之网页授权获取用户信息相关知识感兴趣的朋友通过本文学习吧

在公众号的配置过程中,许多开发者会在菜单中加入HTML5页面,有时在页面内需要访问页面的用户信息,此时就需要网页授权获取用户基本信息

提醒大家:本文介绍讲述的内容是基于yii2.0框架

1、设置授权回调域名:开发 ---> 接口权限

  找到“网页授权获取用户基本信息”,点击后面对应的“修改”,在弹框响应位置填写授权回调域名即可,此处的域名不需要加http:// (关于网页授权回调域名的说明详情可参考公众平台开发者文档)


2、获取授权

  关于OAuth2.0博主参考的是方倍工作室的博文http://www.cnblogs.com/txw1958/p/weixin71-oauth20.html(PS:方倍是一个微信开发大神,其中的微信开发内容还是比较详细的,推荐参考),其中详细剖析了微信官方文档的相关内容,也提供了获取授权的更详细思路和方案。

  实际上,获取用户信息的关键在于获取用户的openid。博主想要实现用户点击公众号菜单打开页面即可自动授权,从而针对该用户进行数据库操作,于是有下面两种方式: 

  (1)利用自定义菜单请求授权页面

    自定义菜单后面会单独写一篇博文,在这里先简述一下通过自定义菜单进行授权,该方法需要高级接口权限,且局限于关注公众号的用户直接从菜单进入页面。

$menu = '{
"button":[
{
"type": "view",
"name": "商城",
"url": "https://open.weixin.qq.com/connect/oauth/authorize?appid=xxx&redirect_uri=http://tx.heivr.com/index.php&response_type=code&scope=snsapi_base&state=#wechat_redirect"
},
{
"name":"快递服务",
"sub_button":[
{
"type":"click",
"name":"发快递",
"key":"express"
},
{
"type":"click",
"name":"快递查询",
"key":"ww"
}
]
},
]
}'; 

需要授权的view直接在url处填写微信提供的授权请求地址,其中:

•appid:填写微信公众平台基本配置中的AppID;
•redirect_uri:填写授权完成后跳转的页面地址,即自己的html5页面;
•state:跳转至回调页面所带参数;
•response_type:网页授权的两种scope,微信官方文档中说明如下:

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

2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
按照此方法点击“商城”即可接收到返回的openid,继而进行下一步用户信息的获取。 

(2)利用JS自动请求授权页面

这个方法相对而言比较笨拙,步骤略复杂,但目前能解决需求还没有研究简化方法,且由于页面的跳转多数情况下访问页面的时间会增加,但相比于前一个方法,该方法可以获取到非关注用户的基本信息。有些程序可能涉及到页面分享,程序没有强制关注但其他用户通过分享直接进入页面也需要记录用户信息,此时可以考虑该方法。(微信开发相关的代码博主封装成工具类调用,这里先贴用到的部分,以后整理完成会全部贴出来并附下载链接)

该方法的思路为:js请求链接获取code ---> 利用code换取openid ---> 得到用户基本信息

a. 编辑配置

为了方便把用到的一些微信参数单独写入一个类,方便修改添加及调用

<&#63;php
namespace common\tools\wechat;
/**
* 微信请求相关配置类库
*/
class ConfigTool {
/**
* 微信配置参数
* @return array 配置参数
*/
public function setConfig() {
// 用于验证微信接口配置信息的Token,可以任意填写
$config['token'] = '自己的token';
// appID
$config['appid'] = '自己的appid';
// appSecret
$config['secret'] = '自己的secret';
// 回调链接地址
$config['redirect_uri'] = 'http://tx.heivr.com/index.php&#63;';
// 是否以 HTTPS 安全协议访问接口
$config['https_request'] = false;
// 授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),
// snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,
// 即使在未关注的情况下,只要用户授权,也能获取其信息)
$config['scope'] = 'snsapi_userinfo';
// 语言
$config['lang'] = 'zh_CN'; // zh_CN 简体,zh_TW 繁体,en 英语
// 微信公众账户授权地址
$config['mp_authorize_url'] = 'https://api.weixin.qq.com/cgi-bin/token';
// 微信公众账户js临时票据地址
$config['jsapi_ticket_url'] = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket';
// 授权地址
$config['authorize_url'] = 'https://open.weixin.qq.com/connect/oauth/authorize';
// 获取access token 的地址
$config['access_token_url'] = 'https://api.weixin.qq.com/sns/oauth/access_token';
// 刷新 token 的地址
$config['refresh_token_url'] = 'https://api.weixin.qq.com/sns/oauth/refresh_token';
// 获取用户信息地址
$config['userinfo_url'] = 'https://api.weixin.qq.com/sns/userinfo';
// 验证access token
$config['valid_token_url'] = 'https://api.weixin.qq.com/sns/auth';
// 上传临时素材地址
$config['media_temp_upload_url'] = 'https://api.weixin.qq.com/cgi-bin/media/upload&#63;';
// 上传永久素材地址
$config['media_forever_upload_url'] = 'https://api.weixin.qq.com/cgi-bin/material/add_material&#63;';
return $config;
}
}

b. https请求工具

<&#63;php
namespace common\tools;
/**
* https请求相关类库
*/
class HttpsTool {
const TIMEOUT = ; // 设置超时时间
private $ch; // curl对象
/**
* 发送curl请求,并获取请求结果
* @param string 请求地址
* @param array 如果是post请求则需要传入请求参数
* @param string 请求方法,get 或者 post, 默认为get
* @param bool 是否以https协议请求
*/
public function send_request($requests, $params = null, $method = 'get', $https = true) {
// 以get方式提交
if ($method == 'get') {
if($params){
$request = $requests . $this->create_url($params);
}else{
$request = $requests;
}
}else{
$request = $requests;
}
$this->ch = curl_init($request);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, );// 设置不显示结果,储存入变量
curl_setopt($this->ch, CURLOPT_TIMEOUT, self::TIMEOUT); // 设置超时限制防止死循环
// 判断是否以https方式访问
if ($https) {
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, ); // 对认证证书来源的检查
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, ); // 从证书中检查SSL加密算法是否存在
}
if ($method == 'post') { // 以post方式提交
//curl_setopt($this->ch, CURLOPT_SAFE_UPLOAD, false); //php .文件上传必加内容,.不需要
curl_setopt($this->ch, CURLOPT_POST, ); // 发送一个常规的Post请求
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $params); // Post提交的数据包
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, );
}
$tmpInfo = curl_exec($this->ch); // 执行操作
if (curl_errno($this->ch)) {
echo 'Errno:'.curl_error($this->ch);//捕抓异常
}
curl_close($this->ch); // 关闭CURL会话
//var_dump($tmpInfo);exit;
return $tmpInfo; // 返回数据
}
/**
* 生成url
*/
public function create_url($data) {
$temp = '&#63;';
foreach ($data as $key => $item) {
$temp = $temp . $key . '=' . $item . '&';
}
return substr($temp, , -);
}
}

关于curl_setopt($this->ch, CURLOPT_SAFE_UPLOAD, false)会在微信图片资源上传博文中详细讲述它出现的心酸史,这里暂时用不到,不做解释

c. 授权基类

<&#63;php 
namespace common\tools\wechat;
use common\tools\wechat\ConfigTool;
use common\tools\HttpsTool;
/**
* Weixin_oauth 类库
*/
class OauthTool {
public $conf;
public function __construct(){
$re = new ConfigTool; 
$this->cOnf= $re->setConfig();
} 
/**
* 生成用户授权的地址
* @param string 自定义需要保持的信息
* @param sting 请求的路由
* @param bool 是否是通过公众平台方式认真
*/
public function authorize_addr($route, $state='', $mp=false) {
if ($mp) {
$data = [
'appid' => $this->conf['appid'],
'secret' => $this->conf['token'],
'grant_type' => 'client_credential'
];
$url = $this->conf['mp_authorize_url'];
} else {
$data = [
'appid' => $this->conf['appid'], //公众号唯一标识
'redirect_uri' => urlencode($this->conf['redirect_uri'] . $route), //授权后重定向的回调链接地址
'response_type' => 'code', //返回类型,此处填写code
'scope'=>$this->conf['scope'], //应用授权作用域
'state'=>$state, //重定向后带上state参数,开发者可以填写任意参数
'#wechat_redirect'=>'' //直接在微信打开链接,可不填,做页面重定向时必须带此参数
];
$url = $this->conf['authorize_url'];
}
$send = new HttpsTool;
//var_dump($url . $send->create_url($data));exit;
return $url . $send->create_url($data);
}
/**
* 获取 access token
* @param string 用于换取access token的code,微信提供
*/
public function access_token($code) {
$data = [
'appid' => $this->conf['appid'],
'secret' => $this->conf['secret'],
'code' => $code,
'grant_type' => 'authorization_code'
];
// 生成授权url
$url = $this->conf['access_token_url'];
$send = new HttpsTool;
return $send->send_request($url, $data);
}
/**
* 获取用户信息
* @param string access token
* @param string 用户的open id
*/
public function userinfo($token, $openid) {
$data = [
'access_token' => $token,
'openid' => $openid,
'lang' => $this->conf['lang']
];
// 生成授权url
$url = $this->conf['userinfo_url'];
$send = new HttpsTool;
return $send->send_request($url, $data);
}
}

d. 授权基类调用及用户数据处理(在控制器调用前,先对用户数据存入或更新)

<&#63;php
namespace wechat\controllers\classes;
use common\tools\wechat\OauthTool;
use common\models\User;
use common\tools\EmojiTool;
/**
* 微信用户基本信息获取
*/
class UserinfoClass {
/**
* 用户授权并获取code 
* @return string 用户code
*/
public function getCode($route, $state){
$re = new OauthTool;
$request = $re->authorize_addr($route, $state);
$code = isset($_GET['code']) &#63; $_GET['code'] : '';
return [$request,$code];
}
/**
* 获取用户信息并写入数据库(之后加参数传给code)
*/
public function info($code) {
$re = new OauthTool;
//获取access token
$access = $re->access_token($code);
$token = json_decode($access,true);
//header("Content-type: text/html; charset=gbk"); 
//获取用户信息
if(count($token) != ) {
$respOnse= $re->userinfo($token['access_token'], $token['openid']);
$user = json_decode($response,true);
//用户昵称转换
//$user['nickname'] = EmojiTool::emoji_trans($user['nickname']);
if($model = User::findOne(['openid' => $user['openid'] ])) { //用户已存在更新数据
$model->attributes = $user;
$model->modify_time = time();
$model->save(false);
}else{ //用户不存在写入
$model = new User;
$model->attributes = $user;
$model->create_time = time();
$model->save(false);
}
}
return isset($model->id) &#63; $model->id : '';
}
} 

e. 控制器调用(这里只贴其中一个方法)

/**
* 产品列表
* @return object 所有可用产品信息
*/
public function actionIndex(){
//判断页面是否自动刷新
if(isset($_GET['state'])) {
$refresh = ;
}else{
$refresh = ;
}
//获取用户code
$user = new UserinfoClass;
$request = $user->getCode('r=store/index', );
//该用户userid
$userid = $user->info($request[]);
$model = new Product;
$list = $model->find()->where(['status' => ])->all();
return $this->render('index',['list' => $list, 'refresh' => $refresh, 'userid' => $userid, 'request' => $request]);
}

程序要求用户打开产品列表即获取用户信息并存入数据库,其中设计了几个变量作用如下:

$refresh:判断页面是否刷新,由于首次打开页面未进行oauth验证时才自动请求验证,避免反复刷新,这里用回调的state参数作为判断依据且设state=1(若有特定参数需要可将state赋值为所需值);

$request:即为验证请求地址

f. 视图自动刷新

只需要在视图中添加以下js代码即可


以上内容给大家介绍了微信开发之网页授权获取用户信息(二)的全部叙述,希望本文分享能够给大家带来帮助。


推荐阅读
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 使用正则表达式爬取36Kr网站首页新闻的操作步骤和代码示例
    本文介绍了使用正则表达式来爬取36Kr网站首页所有新闻的操作步骤和代码示例。通过访问网站、查找关键词、编写代码等步骤,可以获取到网站首页的新闻数据。代码示例使用Python编写,并使用正则表达式来提取所需的数据。详细的操作步骤和代码示例可以参考本文内容。 ... [详细]
  • 在Android中解析Gson解析json数据是很方便快捷的,可以直接将json数据解析成java对象或者集合。使用Gson解析json成对象时,默认将json里对应字段的值解析到java对象里对应字段的属性里面。然而,当我们自己定义的java对象里的属性名与json里的字段名不一样时,我们可以使用@SerializedName注解来将对象里的属性跟json里字段对应值匹配起来。本文介绍了使用@SerializedName注解解析json数据的方法,并给出了具体的使用示例。 ... [详细]
  • 小程序自动授权和手动接入的方式及操作步骤
    本文介绍了小程序支持的两种接入方式:自动授权和手动接入,并详细说明了它们的操作步骤。同时还介绍了如何在两种方式之间切换,以及手动接入后如何下载代码包和提交审核。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
  • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
author-avatar
abc
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有