|
本帖最后由 西昌之家冯齐跃 于 2016-3-9 19:13 编辑
西昌之家是一个从0开始的站点,pc端没有一点基础,我们在运营的时候很痛苦。马甲评论、引导评论都在做,几乎没效果(算了,不找借口了,其实是运营弱暴了),所以就想降低用户参与评论、点赞的门槛(微信里免注册),把微信里的流量利用起来。
有了这么个需求就开始读代码,把Discuz! 的微信登陆和千帆APP的微信绑定代码看了几遍以后,发现Discuz! 微信登陆是没有考虑unionid(这可能也是千帆没有直接打通微信登陆的原因),要实现微信登陆打通有2种方案;
1、修改Disucz! 官方微信登陆插件,增加unionid相关。
优点:能把 pc扫一扫/app/微信内登陆 统一起来;
缺点:要动到官方程序及数据表;服务号oauth回调域名需要邦定站点域名
2、基于Disucz! 微信登陆插件,做登陆绑定的接口。
优点:不用修改Discuz! 代码,少量代码即可实现统一登陆;
缺点:pc端微信扫一扫需要重新开发;
由于我们还运营得有一个微信第三方平台,服务号oauth回调域名被绑定到该站点上了,不想再申请一个服务号专门用来做网站的登陆,所以采用了方案二并写了个接口,用于返回加密后的用户基础资料给到Discuz! 微信登陆接口进行处理。
- $key = $fans['nickname'] . "\t" . $fans['openid'] . "\t" . $fans['unionid'];
- $key = base64_encode(authcode($key, 'ENCODE', AUTHKEY)); // 加密
- $forward = 'http://www.xc163.com/clientapi/wxauth.php?key=' . $key . '&redirect_uri=' . urlencode($forward_url) . '#wechat_redirect';
- header('Location: ' . $forward);
- exit;
复制代码
Discuz! 微信登陆接口wxauth.php的导图:
- <?php
- require_once '../source/class/class_core.php';
- require_once '../source/plugin/wechat/wechat.lib.class.php';
- require_once '../source/plugin/wechat/wechat.class.php';
- require_once '../source/discuz_version.php';
- $discuz = C::app();
- $discuz->init();
- define('IN_WECHAT', strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false);
- define('REDIRECT_URL', 'http://' . $_SERVER['HTTP_HOST'] . '/clientapi/wxoauth.php');
- define('AUTHKEY', $_G['config']['security']['authkey']);
- if (IN_WECHAT == false) exit();
- if (!isset($_GET['redirect_uri'])) exit('redirect_uri empty');
- if (!isset($_GET['key'])) exit('key empty');
- list($nickname, $openid, $unionId) = explode("\t", authcode(base64_decode($_GET['key']), 'DECODE', AUTHKEY));
- if ($openid) {
- dsetcookie('wechatopenid', authcode($openid, 'ENCODE', AUTHKEY), 86400);;
- }
- if ($unionId) {
- dsetcookie('wechatunionid', authcode($unionId, 'ENCODE', AUTHKEY), 86400);
- }
- require_once libfile('function/member');
- if ($openid) {
- // 千帆绑定
- if ($unionId) {
- $wechatuser = DB::fetch_first('SELECT * FROM %t WHERE unionid=%s AND weibotype=%s', array('thirdbind', $unionId, 'wechat'));
- }
- else {
- $wechatuser = DB::fetch_first('SELECT * FROM %t WHERE openid=%s AND weibotype=%s', array('thirdbind', $openid, 'wechat'));
- }
- // Discuz 绑定
- if (!$wechatuser) {
- $wechatuser = DB::fetch_first('SELECT * FROM %t WHERE openid=%s', array('common_member_wechat', $openid, 'wechat'));
- if ($wechatuser) {
- $checkUser = DB::fetch_first('SELECT * FROM %t WHERE uid=%i', array('common_member', $wechatuser['uid']));
- if ($checkUser) {
- DB::insert('thirdbind', array('uid' => $checkUser['uid'], 'nickname' => $checkUser['username'], 'openid' => $openid, 'unionid' => $unionId, 'weibotype' => 'wechat', 'dateline' => time()), false, true);
- }
- }
- }
- if (!$wechatuser) {
- if ($nickname) {
- $defaultusername = substr(WeChatEmoji::clear($nickname), 0, 15);
- loaducenter();
- $user = uc_get_user($defaultusername);
- if (!empty($user)) {
- if (is_numeric($defaultusername)) {
- $defaultusername = 'wx' . cutstr($defaultusername, 5, '') . random(3, 1);
- }
- else {
- $defaultusername = cutstr($defaultusername, 7, '') . random(3, 1);
- }
- }
- }
- else {
- $defaultusername = 'wx' . random(8, 1);
- }
- $uid = WeChat::register($defaultusername, 1);
- // 有可能包含 不允许字符的字符,再随机生成用户名注册一次!
- if (!$uid) {
- $defaultusername = 'wx' . random(8, 1);
- $uid = WeChat::register($defaultusername, 1);
- }
- if ($uid) {
- // 绑定
- WeChatHook::bindOpenId($uid, $openid, 1);
- // 用户被删除的情况
- $thirduser = DB::fetch_first('SELECT * FROM %t WHERE openid=%s AND weibotype=%s', array('thirdbind', $openid, 'wechat'));
- if ($thirduser) {
- DB::update('thirdbind', array('uid' => $uid), array('id' => $thirduser['id']));
- }
- else {
- DB::insert('thirdbind', array('uid' => $uid, 'nickname' => $nickname, 'openid' => $openid, 'unionid' => $unionId, 'weibotype' => 'wechat', 'dateline' => time()), false, true);
- }
- $member['uid'] = $uid;
- $member['username'] = $defaultusername;
- }
- }
- }
- if ($wechatuser) {
- $member = getuserbyuid($wechatuser['uid'], 1);
- setloginstatus($member, 1296000);
- wechat_setloginstatus($wechatuser['uid'], true);
- }
- if ($member) {
- dheader('location: ' . urldecode($_GET['redirect_uri']));
- }
- function wechat_setloginstatus($uid, $login) {
- C::t('#wechat#common_member_wechat')->update($uid, array('status' => $login ? 2 : 1));
- }
复制代码
接口利用Discuz经典加解密函数authcode(),解密接收到的用户基础资料,注册登陆都调用的Discuz微信登陆相关方法,个人感觉还是靠谱的。
目前感觉不足就是昵称和头像,昵称如果出现Emoji表情则随机生成用户名(wx+8位随机字符),头像暂没考虑写入本地…
以上
|
|