Discuz! UCenter 是康盛產品族(Discuz!、UChome、Supesite 等)的核心用戶中心,提供統一註冊、登錄、登出、用戶資料同步等功能。透過 discuz-ucenter-api-for-java 開源庫,Java 應用可輕松接入 UCenter,實現與 Discuz! 論壇的單點登錄(SSO)。本文記錄完整整合流程。
php.ini 啟用 extension=php_curl.dll、extension=php_mbstring.dll。https://yourdomain/uc_server/admin.php)。https://your-java-app/api/uc.php(對應下方 Servlet 映射)127.0.0.1)yunstudio_2024@#$2)下載 discuz-ucenter-api-for-java 專案,將 uc_client.jar(或源碼包)放入專案 WEB-INF/lib 或作為 Module 依賴。
放在 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。<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 發起的同步通知(如用戶在論壇修改密碼、被刪除等)。
@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); // 輸出