千帆云

标题: 根据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! 微信登陆接口进行处理。

  1. $key = $fans['nickname'] . "\t" . $fans['openid'] . "\t" . $fans['unionid'];
  2. $key = base64_encode(authcode($key, 'ENCODE', AUTHKEY)); // 加密
  3. $forward = 'http://www.xc163.com/clientapi/wxauth.php?key=' . $key . '&redirect_uri=' . urlencode($forward_url) . '#wechat_redirect';
  4. header('Location: ' . $forward);
  5. exit;
复制代码


Discuz! 微信登陆接口wxauth.php的导图:



  1. <?php
  2. require_once '../source/class/class_core.php';
  3. require_once '../source/plugin/wechat/wechat.lib.class.php';
  4. require_once '../source/plugin/wechat/wechat.class.php';
  5. require_once '../source/discuz_version.php';
  6. $discuz = C::app();
  7. $discuz->init();

  8. define('IN_WECHAT', strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false);
  9. define('REDIRECT_URL', 'http://' . $_SERVER['HTTP_HOST'] . '/clientapi/wxoauth.php');
  10. define('AUTHKEY', $_G['config']['security']['authkey']);

  11. if (IN_WECHAT == false) exit();
  12. if (!isset($_GET['redirect_uri'])) exit('redirect_uri empty');
  13. if (!isset($_GET['key'])) exit('key empty');

  14. list($nickname, $openid, $unionId) = explode("\t", authcode(base64_decode($_GET['key']), 'DECODE', AUTHKEY));
  15. if ($openid) {
  16.     dsetcookie('wechatopenid', authcode($openid, 'ENCODE', AUTHKEY), 86400);;
  17. }
  18. if ($unionId) {
  19.     dsetcookie('wechatunionid', authcode($unionId, 'ENCODE', AUTHKEY), 86400);
  20. }
  21. require_once libfile('function/member');
  22. if ($openid) {
  23.     // 千帆绑定
  24.     if ($unionId) {
  25.         $wechatuser = DB::fetch_first('SELECT * FROM %t WHERE unionid=%s AND weibotype=%s', array('thirdbind', $unionId, 'wechat'));
  26.     }
  27.     else {
  28.         $wechatuser = DB::fetch_first('SELECT * FROM %t WHERE openid=%s AND weibotype=%s', array('thirdbind', $openid, 'wechat'));
  29.     }
  30.     // Discuz 绑定
  31.     if (!$wechatuser) {
  32.         $wechatuser = DB::fetch_first('SELECT * FROM %t WHERE openid=%s', array('common_member_wechat', $openid, 'wechat'));
  33.         if ($wechatuser) {
  34.             $checkUser = DB::fetch_first('SELECT * FROM %t WHERE uid=%i', array('common_member', $wechatuser['uid']));
  35.             if ($checkUser) {
  36.                 DB::insert('thirdbind', array('uid' => $checkUser['uid'], 'nickname' => $checkUser['username'], 'openid' => $openid, 'unionid' => $unionId, 'weibotype' => 'wechat', 'dateline' => time()), false, true);
  37.             }
  38.         }
  39.     }
  40.     if (!$wechatuser) {
  41.         if ($nickname) {
  42.             $defaultusername = substr(WeChatEmoji::clear($nickname), 0, 15);
  43.             loaducenter();
  44.             $user = uc_get_user($defaultusername);
  45.             if (!empty($user)) {
  46.                 if (is_numeric($defaultusername)) {
  47.                     $defaultusername = 'wx' . cutstr($defaultusername, 5, '') . random(3, 1);
  48.                 }
  49.                 else {
  50.                     $defaultusername = cutstr($defaultusername, 7, '') . random(3, 1);
  51.                 }
  52.             }
  53.         }
  54.         else {
  55.             $defaultusername = 'wx' . random(8, 1);
  56.         }
  57.         $uid = WeChat::register($defaultusername, 1);
  58.         // 有可能包含 不允许字符的字符,再随机生成用户名注册一次!
  59.         if (!$uid) {
  60.             $defaultusername = 'wx' . random(8, 1);
  61.             $uid = WeChat::register($defaultusername, 1);
  62.         }
  63.         if ($uid) {
  64.             // 绑定
  65.             WeChatHook::bindOpenId($uid, $openid, 1);
  66.             // 用户被删除的情况
  67.             $thirduser = DB::fetch_first('SELECT * FROM %t WHERE openid=%s AND weibotype=%s', array('thirdbind', $openid, 'wechat'));
  68.             if ($thirduser) {
  69.                 DB::update('thirdbind', array('uid' => $uid), array('id' => $thirduser['id']));
  70.             }
  71.             else {
  72.                 DB::insert('thirdbind', array('uid' => $uid, 'nickname' => $nickname, 'openid' => $openid, 'unionid' => $unionId, 'weibotype' => 'wechat', 'dateline' => time()), false, true);
  73.             }
  74.             $member['uid'] = $uid;
  75.             $member['username'] = $defaultusername;
  76.         }
  77.     }
  78. }
  79. if ($wechatuser) {
  80.     $member = getuserbyuid($wechatuser['uid'], 1);
  81.     setloginstatus($member, 1296000);
  82.     wechat_setloginstatus($wechatuser['uid'], true);
  83. }
  84. if ($member) {
  85.     dheader('location: ' . urldecode($_GET['redirect_uri']));
  86. }
  87. function wechat_setloginstatus($uid, $login) {
  88.     C::t('#wechat#common_member_wechat')->update($uid, array('status' => $login ? 2 : 1));
  89. }
复制代码

接口利用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