Implementing QQ and Weibo One‑Click Login in a Java Backend
This guide details how to design the backend, database schema, authentication flow, and Java code required to integrate QQ and Weibo one‑click login for a website, covering token handling, user data retrieval, and practical security considerations.
The article explains how to add QQ and Weibo one‑click login to a personal website, focusing on backend design, database schema, and authentication flow using Java.
Backend Design – After third‑party login the only data received are identifiers such as uid (Weibo), openId (QQ) and accessToken. The guide stores these in an OpenUser table and links them to the existing user system via an OpenUser relation.
Database Design – A dedicated OpenUser table holds fields for third‑party IDs, nickname, avatar, gender, etc., allowing unlimited extension.
QQ Login Integration
Real‑name verification – Register as a developer on QQ Connect and complete identity verification.
Application creation – Create a web application on QQ Connect to obtain appId and appKey.
Login flow – A button opens the QQ authorization page using a generated URL. After user consent QQ redirects back with an accessToken (sometimes directly, bypassing the code step).
function openWindow(url, width, height) {
width = width || 600;
height = height || 400;
var left = (window.screen.width - width) / 2;
var top = (window.screen.height - height) / 2;
window.open(url, "_blank", "toolbar=yes, location=yes, directories=no, status=no, menubar=yes, scrollbars=yes, resizable=no, copyhistory=yes, left="+left+", top="+top+", width="+width+", height="+height);
}
function qqLogin() {
var qqAppId = '424323422'; // appId obtained from QQ
var qqAuthPath = 'http://www.test.com/auth'; // callback URL
var state = 'fjdslfjsdlkfd'; // CSRF protection token
openWindow(`https://graph.qq.com/oauth2.0/authorize?response_type=token&client_id=${qqAppId}&redirect_uri=${encodeURIComponent(qqAuthPath)}&state=${state}`);
}Because the hash fragment ( #) containing the token is not sent to the server, a temporary HTML page rewrites the fragment into query parameters:
@RequestMapping("/authqq")
public void authQQ(HttpServletRequest request, HttpServletResponse response) throws Exception {
String html = "<!DOCTYPE html>" +
"<html lang=\"zh-cn\">" +
"<head><title>QQ登录重定向页</title><meta charset=\"utf-8\"/></head>" +
"<body><script type=\"text/javascript\">" +
"location.href = location.href.replace('#', '&').replace('auth_qq', 'auth_qq_redirect');" +
"</script></body></html>";
response.getWriter().print(html);
}After obtaining the accessToken, the backend calls QQ’s API to get the openId and then fetches user profile information (nickname, avatar, gender). Special handling is required for UTF‑8 mb4 characters in nicknames.
// Get openId
String result = HttpsUtil.get("https://graph.qq.com/oauth2.0/me?access_token=" + accessToken);
Map<String, Object> resp = parseQQAuthResponse(result);
String openId = (String)resp.get("openid");
// Get user info
result = HttpsUtil.get("https://graph.qq.com/user/get_user_info?access_token=" + accessToken + "&oauth_consumer_key=" + appId + "&openid=" + openId);
resp = JsonUtil.parseJsonToMap(result);
String nickname = StringUtil.filterUtf8Mb4((String)resp.get("nickname")).trim();
String avatar = (String)resp.get("figureurl_qq_2");
if (StringUtil.isBlank(avatar)) avatar = (String)resp.get("figureurl_2");
String gender = (String)resp.get("gender");Key notes for QQ integration include handling token leakage, ensuring the callback URL matches the registered domain, and dealing with occasional bugs in QQ’s authorization management.
Weibo Login Integration
Real‑name verification – Register on Weibo Open Platform and complete identity verification.
Application creation – Create a web application to obtain appId and appSecret.
Login flow – A button opens the Weibo authorization page; after consent Weibo returns a code which is exchanged for an accessToken and uid.
String params = "client_id=" + appId +
"&client_secret=" + appSecret +
"&grant_type=authorization_code" +
"&redirect_uri=" + URLUtil.encode(authPath) +
"&code=" + code;
String result = HttpsUtil.post("https://api.weibo.com/oauth2/access_token", params);
Map<String, Object> resp = JsonUtil.toObject(result, new TypeReference<Map<String, Object>>(){});
String accessToken = (String)resp.get("access_token");
String uid = (String)resp.get("uid");
int expires = (Integer)resp.get("expires_in");Using the accessToken and uid, the backend fetches user profile data:
String result = HttpsUtil.get("https://api.weibo.com/2/users/show.json?access_token=" + accessToken + "&uid=" + uid);
Map<String, Object> resp = JsonUtil.toObject(result, new TypeReference<Map<String, Object>>(){});
String nickname = (String)resp.get("screen_name");
String avatar = (String)resp.get("avatar_large");
String gender = (String)resp.get("gender"); // "m" or "f"Weibo login is smoother because after the first authorization subsequent logins happen automatically. The guide also lists practical considerations such as API rate limits, error handling, and ensuring HTTPS POST requests.
Both integrations conclude with storing the retrieved user data in the database, creating a session token, and handling subsequent authentication checks.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
