在前面的博文中,我已经完成了discuz与java web在浏览器上的整合,大概原理是利用ucernter作为中介,在java web中登录时,调用uc_user_login()登录,这时候就会返回一段js代码把cookie写在浏览器中,使得两个系统公用相同的cookie以达到同步登录的目的。
我们都知道,很多公司都用使用阿里的钉钉作为办公通讯工具。那么这篇将介绍如何使用融合discuz,java web,钉钉的同步登录!
一、首先先看看钉钉与discuz的整合:
由于钉钉的微应用是根据url去访问的,所以原理是:在url给discuz传送key值和uid的值,discuz服务端在获取key值后知道是钉钉应用的访问,再根据uid判断是哪位用户登录。那么我们需要做的是
1.如何绕开discuz的登录验证。
首先,我们先了解discuz的源码目录框架,在上一篇我转载了别人介绍的目录框架。找到根目录的menber代码:
- <?php
- /**
- * [Discuz!] (C)2001-2099 Comsenz Inc.
- * This is NOT a freeware, use is subject to license terms
- *
- * $Id: member.php 24411 2011-09-19 05:09:03Z monkey $
- */
- define('APPTYPEID', 0);
- define('CURSCRIPT', 'member');
- require './source/class/class_core.php';
- $discuz = C::app();
- $modarray = array('activate', 'clearcookies', 'emailverify', 'getpasswd',
- 'groupexpiry', 'logging', 'lostpasswd',
- 'register', 'regverify', 'switchstatus');
- $mod = !in_array($discuz->var['mod'], $modarray) && (!preg_match('/^\w+$/', $discuz->var['mod']) || !file_exists(DISCUZ_ROOT.'./source/module/member/member_'.$discuz->var['mod'].'.php')) ? 'register' : $discuz->var['mod'];
- define('CURMODULE', $mod);
- $discuz->init();
- if($mod == 'register' && $discuz->var['mod'] != $_G['setting']['regname']) {
- showmessage('undefined_action');
- }
- require libfile('function/member');
- require libfile('class/member');
- runhooks();
- require DISCUZ_ROOT.'./source/module/member/member_'.$mod.'.php';
- ?>
- function on_login() {
- global $_G;
- if($_G['uid']) {
- $referer = dreferer();
- $ucsynlogin = $this->setting['allowsynlogin'] ? uc_user_synlogin($_G['uid']) : '';
- $param = array('username' => $_G['member']['username'], 'usergroup' => $_G['group']['grouptitle'], 'uid' => $_G['member']['uid']);
- showmessage('login_succeed', $referer ? $referer : './', $param, array('showdialog' => 1, 'locationtime' => true, 'extrajs' => $ucsynlogin));
- }
- $from_connect = $this->setting['connect']['allow'] && !empty($_GET['from']) ? 1 : 0;
- $seccodecheck = $from_connect ? false : $this->setting['seccodestatus'] & 2;
- $seccodestatus = !empty($_GET['lssubmit']) ? false : $seccodecheck;
- $invite = getinvite();
- //1. edit && $_GET['app'] != "ding"
- if(!submitcheck('loginsubmit', 1, $seccodestatus) && $_GET['app'] != "ding") {
- //showmessage("11111");//--------------------------------------------
- $auth = '';
- $username = !empty($_G['cookie']['loginuser']) ? dhtmlspecialchars($_G['cookie']['loginuser']) : '';
- if(!empty($_GET['auth'])) {
- list($username, $password, $questionexist) = explode("\t", authcode($_GET['auth'], 'DECODE'));
- $username = dhtmlspecialchars($username);
- $auth = dhtmlspecialchars($_GET['auth']);
- }
- $cookietimecheck = !empty($_G['cookie']['cookietime']) || !empty($_GET['cookietime']) ? 'checked="checked"' : '';
- if($seccodecheck) {
- $seccode = random(6, 1) + $seccode{0} * 1000000;
- }
- if($this->extrafile && file_exists($this->extrafile)) {
- require_once $this->extrafile;
- }
- $navtitle = lang('core', 'title_login');
- include template($this->template);
- } else {
- <span style="color:#ff0000;">//钉钉登录的处理函数在这里----------------------------------------------
- if($_GET['app'] == "ding" && $_GET['ding_uid'] > 0){
- //showmessage("into1");//--------------------------------------------
- $result = userlogin1($_GET['ding_uid']);
- }else { // 如果不是</span>
- if(!empty($_GET['auth'])) {
- list($_GET['username'], $_GET['password']) = daddslashes(explode("\t", authcode($_GET['auth'], 'DECODE')));
- }
- if(!($_G['member_loginperm'] = logincheck($_GET['username']))) {
- showmessage('login_strike');
- }
- if($_GET['fastloginfield']) {
- $_GET['loginfield'] = $_GET['fastloginfield'];
- }
- $_G['uid'] = $_G['member']['uid'] = 0;
- $_G['username'] = $_G['member']['username'] = $_G['member']['password'] = '';
- if(!$_GET['password'] || $_GET['password'] != addslashes($_GET['password'])) {
- showmessage('profile_passwd_illegal');
- }
- $result = userlogin($_GET['username'], $_GET['password'], $_GET['questionid'], $_GET['answer'], $this->setting['autoidselect'] ? 'auto' : $_GET['loginfield'], $_G['clientip']);
- } // end else
- $uid = $result['ucresult']['uid'];
- if(!empty($_GET['lssubmit']) && ($result['ucresult']['uid'] == -3 || $seccodecheck)) {
- $_GET['username'] = $result['ucresult']['username'];
- $this->logging_more($result['ucresult']['uid'] == -3);
- }
- if($result['status'] == -1) {
- if(!$this->setting['fastactivation']) {
- $auth = authcode($result['ucresult']['username']."\t".FORMHASH, 'ENCODE');
- showmessage('location_activation', 'member.php?mod='.$this->setting['regname'].'&action=activation&auth='.rawurlencode($auth).'&referer='.rawurlencode(dreferer()), array(), array('location' => true));
- } else {
- $init_arr = explode(',', $this->setting['initcredits']);
- $groupid = $this->setting['regverify'] ? 8 : $this->setting['newusergroupid'];
- C::t('common_member')->insert($uid, $result['ucresult']['username'], md5(random(10)), $result['ucresult']['email'], $_G['clientip'], $groupid, $init_arr);
- $result['member'] = getuserbyuid($uid);
- $result['status'] = 1;
- }
- }
- if($result['status'] > 0) {
- //showmessage("1111111111");//--------------------------------------------------------
- if($this->extrafile && file_exists($this->extrafile)) {
- require_once $this->extrafile;
- }
- setloginstatus($result['member'], $_GET['cookietime'] ? 2592000 : 0);
- checkfollowfeed();
- if($_G['member']['lastip'] && $_G['member']['lastvisit']) {
- dsetcookie('lip', $_G['member']['lastip'].','.$_G['member']['lastvisit']);
- }
- C::t('common_member_status')->update($_G['uid'], array('lastip' => $_G['clientip'], 'lastvisit' =>TIMESTAMP, 'lastactivity' => TIMESTAMP));
- $ucsynlogin = $this->setting['allowsynlogin'] ? uc_user_synlogin($_G['uid']) : '';
- if($invite['id']) {
- $result = C::t('common_invite')->count_by_uid_fuid($invite['uid'], $uid);
- if(!$result) {
- C::t('common_invite')->update($invite['id'], array('fuid'=>$uid, 'fusername'=>$_G['username']));
- updatestat('invite');
- } else {
- $invite = array();
- }
- }
- if($invite['uid']) {
- require_once libfile('function/friend');
- friend_make($invite['uid'], $invite['username'], false);
- dsetcookie('invite_auth', '');
- if($invite['appid']) {
- updatestat('appinvite');
- }
- }
- $param = array(
- 'username' => $result['ucresult']['username'],
- 'usergroup' => $_G['group']['grouptitle'],
- 'uid' => $_G['member']['uid'],
- 'groupid' => $_G['groupid'],
- 'syn' => $ucsynlogin ? 1 : 0
- );
- $extra = array(
- 'showdialog' => true,
- 'locationtime' => true,
- 'extrajs' => $ucsynlogin
- );
- $loginmessage = $_G['groupid'] == 8 ? 'login_succeed_inactive_member' : 'login_succeed';
- $location = $invite || $_G['groupid'] == 8 ? 'home.php?mod=space&do=home' : dreferer();
- if(empty($_GET['handlekey']) || !empty($_GET['lssubmit'])) {
- if(defined('IN_MOBILE')) {
- showmessage($loginmessage, $location, $param, array('location' => true));
- } else {
- if(!empty($_GET['lssubmit'])) {
- if(!$ucsynlogin) {
- $extra['location'] = true;
- }
- showmessage($loginmessage, $location, $param, $extra);
- } else {
- $href = str_replace("'", "\'", $location);
- showmessage('location_login_succeed', $location, array(),
- array(
- 'showid' => 'succeedmessage',
- 'extrajs' => '<script type="text/javascript">'.
- 'setTimeout("window.location.href =\''.$href.'\';", 3000);'.
- '$(\'succeedmessage_href\').href = \''.$href.'\';'.
- '$(\'main_message\').style.display = \'none\';'.
- '$(\'main_succeed\').style.display = \'\';'.
- '$(\'succeedlocation\').innerHTML = \''.lang('message', $loginmessage, $param).'\';</script>'.$ucsynlogin,
- 'striptags' => false,
- 'showdialog' => true
- )
- );
- }
- }
- } else {
- showmessage($loginmessage, $location, $param, $extra);
- }
- } else {
- $password = preg_replace("/^(.{".round(strlen($_GET['password']) / 4)."})(.+?)(.{".round(strlen($_GET['password']) / 6)."})$/s", "\\1***\\3", $_GET['password']);
- $errorlog = dhtmlspecialchars(
- TIMESTAMP."\t".
- ($result['ucresult']['username'] ? $result['ucresult']['username'] : $_GET['username'])."\t".
- $password."\t".
- "Ques #".intval($_GET['questionid'])."\t".
- $_G['clientip']);
- writelog('illegallog', $errorlog);
- loginfailed($_GET['username']);
- $fmsg = $result['ucresult']['uid'] == '-3' ? (empty($_GET['questionid']) || $answer == '' ? 'login_question_empty' : 'login_question_invalid') : 'login_invalid';
- if($_G['member_loginperm'] > 1) {
- showmessage($fmsg, '', array('loginperm' => $_G['member_loginperm'] - 1));
- } elseif($_G['member_loginperm'] == -1) {
- showmessage('login_password_invalid');
- } else {
- showmessage('login_strike');
- }
- }
- }
- }
然后 在function的的function/function_menber.php中根据userlogin()的代码加入钉钉认证的userlogin1()
- //钉钉认证
- function userlogin1($uid) {
- $return = array();
- $member = getuserbyuid($uid, 1);
- $return['member'] = $member;
- $return['status'] = 1;
- return $return;
- }
- //end
加上代码后,就可以用url访问:http://localhost/member.php?mod=logging&action=login&app=ding&ding_uid=9
ok!在浏览器直接输入url,成功登陆,退出再登录,成功!(注意:每次都要退出后再登录)
2.如何绕开discuz的登录验证(根据discuz用户账号)。
上面的1用uid来绕开很方便,用username绕开好像也不难(前提是你熟悉discuz的数据库操作机制)。因为钉钉的接口获取的是username的值(下一篇会讲),所以这里需要根据username来绕开登录验证。于是去找getuserbyusername()的函数,你会发觉找不到,首先这个函数是一开始的时候就通过function_core.php中加载的,在这个函数中却没有getuserbyusername这个函数,于是乎想自己写,但是自己不熟悉php(本人是java程序猿)。耗了很久时间才搞懂里面C::t('common_member_archive')>fetch($uid);意思是从/source/class/table文件夹内的table_common_member_archive.php里面提取fetch的函数。于是乎根据表来找,我们要获取用户的数据,那么就应该通过table_common_member.php这个函数,很惊奇地就会发现里面有fetch_by_username()函数于是乎,一切都迎刃而解!!
总结:
1.C::t('common_member_archive')>fetch($uid);意思是从/source/class/table文件夹内的table_common_member_archive.php里面提取fetch的函数
2.区table_common_member.php这个函数找相关函数
3.自己组合代码。