阅读本章教程前请先阅读系列教程的第一章

微信开发需要一定的代码能力和Linux基本操作,完全不懂的请跳过本教程

这个教程只是为了演示功能,并没有按照Joomla扩展的开发规范开发成插件,仅供参考代码逻辑,请勿直接用于生产环境

网页授权获取用户基本信息

原理概述:

网页授权,也就是一般所说的第三方登录,把微信的凭证作为身份认证。

微信的网页授权有两种应用场景:

第一种是在微信客户端内,通过微信内置浏览器来访问网站(微网站)。

第二种是在微信之外,通过PC端(手机、平板)通过浏览器访问目标网站。

这两种场景本质上没有太大区别,实现形式上略有不同。

微信开发

假设,我作为www.xingzai.org网站的所有者,为了实现微信登录,要做的第一步是引导用户到微信身份认证的服务器进行授权。在这一步,上述所说的第一种场景,由于是在微信内,用户的微信实际上已经是登录状态,用户就可以直接看到授权页面,如下:

2016052608.png

而在第二种场景下,由于是在微信外,需要把微信身份认证的服务器的地址转换成一个二维码,并提示用户打开微信客户端,使用扫一扫功能扫描该二维码,用户扫描之后,才会看到上面的授权页面

2016052609.png

不管是第一种或者第二种,当用户同意授权,点击确认登录,微信身份认证服务器会把用户重定向到你的网站,平且传来一个CODE,这个CODE就是一个凭证,再通过这个CODE就可以换取到微信提供的该用户的openid以及昵称头像等信息。这个openid对微信用户来说是唯一的,也是不变的。通过这一点,我们就可以把openid作为身份的表示。

假设一个微信openid是a1b2c3d4e5的用户第一次登录我的网站,并创建了一个账号为A,我把他的openid a1b2c3d4e5和账号A的对应关系存在我的数据库,那么这个用户以后再使用微信登录时,我的服务器就会知道openid为a1b2c3d4e5的微信用户想要登录,就直接为他创建A账号的会话。

我再整理一下这中间的几次认证关系。

假设A用户想要登录B网站。B网站要做的就是通过一个链接(或二维码形式的链接)把A引导到微信认证服务器。这个链接同时要包含B网站的appid和重定向url。微信服务器通过这两个参数知道了是B网站把这个用户引导到我这来的。这是微信服务器对网站的身份认证。

这时候如果A用户正在用微信内置浏览器访问B网站,微信会用户确认授权(用户是用微信内置浏览器网站,所以微信当然知道这个用户是A)。

如果用户是坐在电脑前用浏览器访问B网站,那么就需要一个确认用户身份的过程,所以B网站在电脑端展示的是一个带参数的二维码微信认证服务器地址,用户A打开了自己的微信(微信对用户的身份认证),通过扫一扫扫描二维码,这一过程让微信服务器知道了是A被B网站引导来的。

微信把上述两种不同的场景的身份认证,分别交给了两个平台来处理,分别是微信公众平台和微信开放平台。下面的代码部分,讲第一种场景的实现方式,也就是用户通过微信内置浏览器访问网站的网页授权(微信公众平台)。

下面正式开始

前期准备工作:

请参考本系列教程第一章,这里只是简略提一下

1.一台线上Linux主机,我在这台主机的/var/www/html/joomla/目录下运行着我的Joomla网站,现在为这个joomla站实现微信内置浏览器访问时的第三方登录。

在/var/www/html/joomla/下新建一个weixin目录作为开发目录

在这个/var/www/html/joomla/weixin/目录下安装composer 和 easywechat SDK

2.一个微信公众号

配置方式参考教程第一章

开发工作:

1.在joomla根目录下新建一个myconfig.php,内容如下:

<?php
define('_JEXEC', 1);
define('DS', DIRECTORY_SEPARATOR);  
define('JPATH_BASE', dirname(__FILE__) );
require_once (JPATH_BASE.DS.'includes'.DS.'defines.php');  
require_once (JPATH_BASE.DS.'includes'.DS.'framework.php');  
$mainframe =JFactory::getApplication('site');  
$mainframe->initialise();

2.在/var/www/html/joomla/weixin/目录下新建两个文件,user.php和callback.php,user.php是入口,callback.php是回调地址

3.在公众号中建立一个菜单,指向user.php(把user.php作为微信用户跳到joomla网站的入口)

2016052610.png

4.user.php代码

<?php
//引入自定义的外置脚本入口文件
include '/var/www/html/joomla/myconfig.php';
//引入composer入口文件
include '/var/www/html/joomla/weixin/vendor/autoload.php';
//引入easywechat主项目的入口类
use EasyWeChat\Foundation\Application;
//配置参数
$config = [
    'debug'     => true,
    'app_id'    => '【微信公众号appid】',
    'secret'    => '【微信公众号appsecret】',
    'token'     => '【微信公众号自定义token】',
    'log' => [
        'level' => 'debug',
        'file'  => '/tmp/easywechat.log',
    ],
    'oauth' => [
      'scopes'   => ['snsapi_userinfo'],
	//回调地址
      'callback' => '/joomla/weixin/callback.php',
    ],
];
//使用配置初始化一个项目实例
$app = new Application($config);
//从项目实例中得到一个oauth应用实例
$oauth = $app->oauth;
//得到joomla当前用户
$user = JFactory::getUser();
//判断用户登录状态
if (!$user->id) {
	//未登录,引导用户到微信服务器授权
        $oauth->redirect()->send();

}else{
        //已登录状态,重定向到joomla首页
	$targetUrl = 'http://【域名】/joomla/index.php';
	header('location:'. $targetUrl); // 跳转到业务页面
}

5.Callback.php代码

<?php
include '/var/www/html/joomla/myconfig.php';
include '/var/www/html/joomla/weixin/vendor/autoload.php';
use EasyWeChat\Foundation\Application;
//配置参数
$config = [
    'debug'     => true,
    'app_id'    => '【微信公众号appid】',
    'secret'    => '【微信公众号appsecret】',
    'token'     => '【微信公众号自定义token】',
    'log' => [
        'level' => 'debug',
        'file'  => '/tmp/easywechat.log',
    ],
];

$app = new Application($config);
$oauth = $app->oauth;
// 获取 OAuth 授权结果用户信息
$user = $oauth->user();
$user = $user->toArray();
//获得openid
$openid = $user['id'];
//通过openid找到user在joomla系统内的id
//这里应该有一张数据表用来记录joomla内用户的id和openid之间的一一对应关系
//当用户第一次使用微信授权登录时,应该提示用户注册或者绑定已有账号,把用户的openid和用户的在joomla的id写入上述的表中
//当用户第二次通过微信授权登录时,直接通过openid在这张表里查询到用户的id,然后生成joomla的会话
//这里把过程省略..假设得出结果user在系统内的id为270(我joomla的管理员id)
$uid =270; 
$instance = JUser::getInstance();
$instance->load($uid);
$session = JFactory::getSession();
//生成会话
$session->set('user', $instance);
$targetUrl = 'http://【域名】/joomla/index.php';
// 跳转到joomla首页
header('location:'. $targetUrl); 

 附录:

存放openid和userid的表结构,仅供参考

2016052611.png

最终实现效果,点击跳转后已经是登录状态

2016052612.png