千帆云
标题:
根据unionid打通千帆APP微信登陆,附DEMO
[打印本页]
作者:
西昌之家冯齐跃
时间:
2016-3-1 17:35
标题:
根据unionid打通千帆APP微信登陆,附DEMO
本帖最后由 西昌之家冯齐跃 于 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的导图:
西昌之家 (1).png
(60.02 KB, 下载次数: 151)
下载附件
2016-3-1 17:09 上传
<?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位随机字符),头像暂没考虑写入本地…
以上
作者:
西昌之家冯齐跃
时间:
2016-3-1 17:42
另外历史的微信登陆存在一个问题,如果站点开启了微社区,并且选择的公众账号类型为“无公众号/订阅号/未认证服务号”。那么历史存留账号想要统一,个人认为不可能,因为获取用户资料的是康盛的微社区服务号,并不是站点自己的。:D
作者:
泰安网吴昊
时间:
2016-3-2 16:55
我们考虑第一阶段,不允许微信直接生成账户
微信登录只做2个场景
1\论坛已注册的账户,可以进行微信绑定,但是必须有账户,或者注册新的账户,整个流程不能省
2\千帆APP微信登录和注册过的账户,在PC端进行扫码登录
第二个阶段是冯总说的,可以直接评论什么的,这个目前我们还不敢尝试,只想把前面的场景实现了
其实就是类似于QQ的,微信注册在PC端,其实还是要重新走一遍的
作者:
千帆祥子
时间:
2016-3-9 14:05
感谢冯总的分享 很棒
作者:
千帆运营杜茗
时间:
2016-3-9 14:11
感谢冯总!厉害厉害
作者:
昆山论坛李峰
时间:
2016-3-28 13:57
感谢冯总!厉害厉害
作者:
看吕梁白力强
时间:
2016-4-14 20:38
虽然没能力实现,但是也感谢.坐等千帆.
欢迎光临 千帆云 (http://bbs.qianfanyun.com/)
Powered by Discuz! X3.2