首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

Java (JSP) 整合 Discuz! UCenter 實現同步登錄(單點登錄 SSO)完整指南

     編輯:關於JSP

Discuz! UCenter 是康盛產品族(Discuz!、UChome、Supesite 等)的核心用戶中心,提供統一註冊、登錄、登出、用戶資料同步等功能。透過 discuz-ucenter-api-for-java 開源庫,Java 應用可輕松接入 UCenter,實現與 Discuz! 論壇的單點登錄(SSO)。本文記錄完整整合流程。

架構原理

  • UCenter Server:獨立部署的 PHP 應用,管理用戶核心資料、提供 API 接口。
  • Application Client (Java):你的 Java Web 應用,作為 UCenter 的一個「應用」,通過 API 與 Server 通訊。
  • 通訊流程:Client 發送 API 請求(含簽名驗證)→ Server 處理並返回 XML → Client 解析結果並執行本地登錄/同步 Cookie。

環境準備

  1. Apache + PHP:建議 PHP 5.3~5.6(Discuz! X3.1 相容性最佳),Apache 2.2/2.4。注意 php.ini 啟用 extension=php_curl.dll、extension=php_mbstring.dll。
  2. Discuz! X3.1 (UTF-8):安裝時勾選「全新安裝含 UCenter」,或單獨安裝 UCenter 1.5+。
  3. Java 專案:Maven/Gradle 專案,JDK 1.7+,Servlet 容器(Tomcat 7+)。

UCenter Server 端配置

  1. 登入 UCenter 管理後台(https://yourdomain/uc_server/admin.php)。
  2. 「應用管理」→「添加應用」:
    • 應用類型:自定義
    • 應用名稱:你的 Java 系統名稱
    • 應用 URL:https://your-java-app/api/uc.php(對應下方 Servlet 映射)
    • IP:Java 應用伺服器 IP(本機測試填 127.0.0.1)
    • 通訊金鑰(UC_KEY):自定義強金鑰,如 yunstudio_2024@#$
    • 應用 ID(UC_APPID):系統自動分配,記下來(如 2)
  3. 啟用「同步登錄」「同步登出」「同步註冊」等選項。

Java Client 端整合步驟

1. 引入依賴

下載 discuz-ucenter-api-for-java 專案,將 uc_client.jar(或源碼包)放入專案 WEB-INF/lib 或作為 Module 依賴。

2. 配置 config.properties

放在 src/main/resources(Classpath 根目錄):

# UCenter API 配置
UC_API=https://your-discuz-domain/uc_server
UC_IP=127.0.0.1
UC_KEY=yunstudio_2024@#$
UC_APPID=2
UC_CONNECT=
  • UC_API:UCenter Server 入口,必須可從 Java 伺服器網路訪問。
  • UC_KEY:與 Server 端「通訊金鑰」完全一致。
  • UC_APPID:Server 端分配的應用 ID。

3. 註冊 UCenter 接收 Servlet (web.xml)

<servlet>
    <servlet-name>ucApi</servlet-name>
    <servlet-class>com.fivestars.interfaces.bbs.api.UC</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>ucApi</servlet-name>
    <url-pattern>/api/uc.php</url-pattern>
</servlet-mapping>

此 Servlet 負責接收 UCenter Server 發起的同步通知(如用戶在論壇修改密碼、被刪除等)。

4. 實現登錄業務邏輯 (LoginServlet.java)

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    private Client ucClient = new Client(); // 來自 uc_client.jar

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        // 1. 調用 UCenter 驗證用戶
        String result = ucClient.uc_user_login(username, password);
        List<String> userInfo = XMLHelper.uc_unserialize(result); // 解析 XML 返回

        if (userInfo.size() > 0) {
            int uid = Integer.parseInt(userInfo.get(0));
            String uname = userInfo.get(1);
            String pwd = userInfo.get(2);
            String email = userInfo.get(3);

            if (uid > 0) {
                // 2. 登錄成功:生成同步登錄 JS 代碼(關鍵步驟!)
                String synLoginScript = ucClient.uc_user_synlogin(uid);
                
                // 3. 本地系統建立 Session/Token
                HttpSession session = req.getSession();
                session.setAttribute("userId", uid);
                session.setAttribute("username", uname);
                
                // 4. 寫入 Auth Cookie(供同域/跨域識別)
                Cookie authCookie = new Cookie("auth", ucClient.uc_authcode(pwd + "\t" + uid, "ENCODE"));
                authCookie.setMaxAge(365 * 24 * 3600); // 1 年
                authCookie.setPath("/");
                resp.addCookie(authCookie);
                
                Cookie userCookie = new Cookie("uchome_loginuser", uname);
                userCookie.setMaxAge(365 * 24 * 3600);
                userCookie.setPath("/");
                resp.addCookie(userCookie);

                // 5. 返回結果(包含同步登錄 JS,前端執行後即可自動登錄 Discuz!)
                resp.setContentType("text/html;charset=UTF-8");
                PrintWriter out = resp.getWriter();
                out.println("登錄成功:" + uname);
                out.println(synLoginScript); // 輸出 
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved