Java应用集成Discuz认证

目前参与开发的一个项目需要集成Discuz论坛,就是在门户网站登录后,用户点击论坛入口即可自动完成登录,集成之路有点曲折,所以要记录一下….

1.配置UCenter

UCenter是discuz自带的用户统一系统,可以配置第三方应用来完成认证操作.

Ucenter设置

以上为UCenter的设置.

2.添加第三方应用(打开UCenter菜单以管理员方式登录)

添加应用

点击添加新应用

添加新应用

提交后查看通信状态(失败请看下面)

通信状态

3.编写UCenter对接接口

与UCenter通信的这部分,有大佬以前写过了,直接放到项目里就好了.

image-20200414183647360

下载地址:https://share.weiyun.com/5zJjNSC

这个源文件是在web.xml配置servlet接口进行的,可以改写下.(记得删除了UC中的get方法及继承类)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * @author Gary
 * @since 2020-04-13 10:57
 */
@Controller
public class UCController {

    @RequestMapping("/uc.php")
    @ResponseBody
    public void get(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String result = new UC().doAnswer(request, response);
        response.getWriter().print(result);
    }

    @RequestMapping("/dz/login")
    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        String email = request.getParameter("email");
        Client client = new Client();
        String res = client.uc_user_register(name, password, email);
        int i = Integer.parseInt(res);
        if (i == -3 || i > 1) {
            String userLogin = client.uc_user_login(name, password);
            LinkedList<String> rs = XMLHelper.uc_unserialize(userLogin);
            if (rs.size() > 0) {
                int $uid = Integer.parseInt(rs.get(0));
                String $username = rs.get(1);
                String $password = rs.get(2);
                String $email = rs.get(3);
                if ($uid > 0) {
                    response.addHeader("P3P", " CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\"");

                    String $ucsynlogin = client.uc_user_synlogin($uid);
                    System.out.println($ucsynlogin);
                    Cookie auth = new Cookie("auth", client.uc_authcode($password + "\t" + $uid, "ENCODE"));
                    auth.setMaxAge(31536000);
                    auth.setDomain("192.168.137.4");
                    auth.setPath("/");
                    response.addCookie(auth);
                    response.setHeader("P3P", " CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\"");
                    Cookie user = new Cookie("uchome_loginuser", $username);
                    user.setDomain("192.168.137.4");
                    user.setPath("/");
                    response.addCookie(user);
                    int i1 = $ucsynlogin.lastIndexOf("src=\"") + 5;
                    int i2 = $ucsynlogin.indexOf("\" reload");
                    String substring = $ucsynlogin.substring(i1, i2);
                    System.out.println(substring);
                    //response.getWriter().write($ucsynlogin);
                    response.sendRedirect(substring);
                    //response.getWriter().flush();

                }
            }
        }
    }
}

我这里截取的字符串内容是UCenter返回的js链接,这个链接用于设置cookie的,这个功能不完善,仅供参考.

4.修改UCenter源代码(不需要首次激活的情况下)

因为在UCenter注册的用户,不会同步到discuz的用户库,登录的时候必须登录discuz激活才行,

在uc_server/data/config.inc.php,定义下discuz数据库

1
define('DISCUZ_DBTABLEPRE', '`dz_fanlisky_cn`.pre_');

在api/uc.php下修改设置cookie后的操作,就是上面返回的script链接

1
2
3
4
5
6
7
8
9
	if(in_array($get['action'], array('test', 'deleteuser', 'renameuser', 'gettag', 'synlogin', 'synlogout', 'updatepw', 'updatebadwords', 'updatehosts', 'updateapps', 'updateclient', 'updatecredit', 'getcredit', 'getcreditsettings', 'updatecreditsettings', 'addfeed'))) {
		$uc_note = new uc_note();
		echo call_user_func(array($uc_note, $get['action']), $get, $post);
        #设置跳转
		header("Location: http://192.168.137.4/forum.php");
		exit();
	} else {
		exit(API_RETURN_FAILED);
	}

在uc_server/model/user.php 修改用户同步

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function add_user($username, $password, $email, $uid = 0, $questionid = '', $answer = '', $regip = '') {
		$regip = empty($regip) ? $this->base->onlineip : $regip;
		$salt = substr(uniqid(rand()), -6);
		$password = md5(md5($password).$salt);
		$sqladd = $uid ? "uid='".intval($uid)."'," : '';
		$sqladd .= $questionid > 0 ? " secques='".$this->quescrypt($questionid, $answer)."'," : " secques='',";
		$this->db->query("INSERT INTO ".UC_DBTABLEPRE."members SET $sqladd username='$username', password='$password', email='$email', regip='$regip', regdate='".$this->base->time."', salt='$salt'");
		$uid = $this->db->insert_id();
		$this->db->query("INSERT INTO ".UC_DBTABLEPRE."memberfields SET uid='$uid'");
		  // BEGIN
    $this->db->query("INSERT INTO ".DISCUZ_DBTABLEPRE."common_member SET uid='$uid', username='$username', password='$password', email='$email', adminid='0', groupid='10', regdate='".$this->base->time."', credits='0', timeoffset='9999'");
    $this->db->query("INSERT INTO ".DISCUZ_DBTABLEPRE."common_member_status SET uid='$uid', regip='$regip', lastip='$regip', lastvisit='".$this->base->time."', lastactivity='".$this->base->time."', lastpost='0', lastsendmail='0'");
    $this->db->query("INSERT INTO ".DISCUZ_DBTABLEPRE."common_member_profile SET uid='$uid'");
    $this->db->query("INSERT INTO ".DISCUZ_DBTABLEPRE."common_member_field_forum SET uid='$uid'");
    $this->db->query("INSERT INTO ".DISCUZ_DBTABLEPRE."common_member_field_home SET uid='$uid'");
    $this->db->query("INSERT INTO ".DISCUZ_DBTABLEPRE."common_member_count SET uid='$uid', extcredits1='0', extcredits2='0', extcredits3='0', extcredits4='0', extcredits5='0', extcredits6='0', extcredits7='0', extcredits8='0'");
    // END
		return $uid;
	}

至此,就完成了登录操作,其他的操作自己探索吧……

对了,访问http://localhost:8080/api/dz/login?name=zdddali&password=123456&email=357078415@qq.com 体验一下.