How to Integrate QQ Login in Spring Boot: Step‑by‑Step Guide

This tutorial walks you through registering a QQ Connect application, adding the required Maven dependency, creating the login page, implementing the Spring Boot controller and AuthComment utility class, configuring Freemarker, and handling the OAuth flow to achieve seamless QQ authentication in a Java backend.

Programmer DD
Programmer DD
Programmer DD
How to Integrate QQ Login in Spring Boot: Step‑by‑Step Guide

QQ Connect Account Registration

Visit https://connect.qq.com/ , create a new application, and fill in the required information. After submission you can find the APP ID and APP Key in the application management console.

Adding the QQ Login Dependency

<!-- Third‑party QQ login -->
<dependency>
    <groupId>com.qq</groupId>
    <artifactId>Sdk4J</artifactId>
    <version>2</version>
</dependency>

Login Page

<button type="submit" class="btn btn-default" onclick="qqLogin()">qq登录</button>
function qqLogin() {
    window.open("/login/qqLogin", "TencentLogin");
}

Login Controller Implementation

package com.gbq.boot.web.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.gbq.boot.web.bean.User;
import com.gbq.boot.web.comment.qqLoginComment.AuthComment;
import com.gbq.boot.web.service.UserService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

/**
 * Login Controller
 */
@RestController
@RequestMapping("/login")
public class LoginController {

    @Resource
    private UserService userService;
    @Resource
    private AuthComment authComment;

    @RequestMapping("/index")
    public ModelAndView index(@ModelAttribute("user") User user) {
        return new ModelAndView("/shop/index", "user", user);
    }

    @RequestMapping("/login.html")
    public ModelAndView toLogin() {
        return new ModelAndView("login");
    }

    @RequestMapping("/qqLogin")
    public void qqLogin(HttpServletResponse response) throws Exception {
        String state = StrUtil.uuid();
        String url = authComment.getAuthUrl(state);
        System.out.println(url);
        response.sendRedirect(url);
    }

    @GetMapping("/redirect")
    public ModelAndView getData(@RequestParam(value = "code") String code, RedirectAttributes model) {
        String accessToken = authComment.getAccessToken(code);
        System.out.println("accessToken" + accessToken);
        String openId = authComment.getOpenId(accessToken);
        System.out.println("openId" + openId);
        JSONObject userInfo = authComment.getUserInfo(accessToken, openId);
        String myName = userInfo.getString("nickname");
        User user = new User(null, "", "111111", myName, System.currentTimeMillis(), "是",
                userInfo.getString("figureurl_2"), userInfo.getString("gender"),
                1, 1, "", "", openId);
        User usr = userService.findUsrByOpenId(openId);
        if (usr != null) {
            user.setId(usr.getId());
            userService.updateById(user);
        } else {
            userService.insert(user);
        }
        model.addFlashAttribute("user", user);
        return new ModelAndView("redirect:/login/index");
    }
}

AuthComment Utility Class

package com.gbq.boot.web.comment.qqLoginComment;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.commons.io.IOUtils.toByteArray;

@Component
public class AuthComment {

    private static final String AUTHORIZATION_URL = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s";
    private static final String ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s";
    private static final String OPEN_ID_URL = "https://graph.qq.com/oauth2.0/me?access_token=%s";
    private static final String USER_INFO_URL = "https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s";
    private static final String CALLBACK_URL = "http://127.0.0.1:8080/login/redirect";
    private static final String APP_ID = "你的id"; // replace with your APP ID
    private static final String APP_SECRET = "你的key"; // replace with your APP Key

    public String getAuthUrl(String scope) {
        return String.format(AUTHORIZATION_URL, APP_ID, CALLBACK_URL, scope);
    }

    public String getAccessToken(String code) {
        String url = String.format(ACCESS_TOKEN_URL, APP_ID, APP_SECRET, code, CALLBACK_URL);
        String result = getUrl(url);
        return getMatcher(result, "access_token=(\\w*)&");
    }

    public String getOpenId(String accessToken) {
        String url = String.format(OPEN_ID_URL, accessToken);
        String result = getUrl(url);
        return getMatcher(result, "openid\":\"(\\w*)\"");
    }

    public JSONObject getUserInfo(String accessToken, String openId) {
        String url = String.format(USER_INFO_URL, accessToken, APP_ID, openId);
        String result = getUrl(url);
        return JSON.parseObject(result);
    }

    private String getMatcher(String result, String patternStr) {
        Pattern p = Pattern.compile(patternStr);
        Matcher m = p.matcher(result);
        m.find();
        return m.group(1);
    }

    private String getUrl(String urlStr) {
        try {
            URL url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5 * 1000);
            conn.setRequestMethod("GET");
            InputStream in = conn.getInputStream();
            byte[] data = toByteArray(in);
            return new String(data, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Freemarker Configuration (Spring Boot)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

freemarker:
  template-loader-path: classpath:/templates/
  suffix: .ftl
  cache: false
  charset: UTF-8
  check-template-location: true
  content-type: text/html
  enabled: true

mvc:
  view:
    prefix: /templates/
    suffix: .html
  static-path-pattern: /static/**

Success Page Example

<span>欢迎你,${user.name}</span>

After completing the above steps, the application can redirect users to QQ for authentication, retrieve the access token, openId, and user profile (nickname, avatar URLs, etc.), and log the user in using the data stored in the backend.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendSpring BootAuthenticationOAuthQQ Login
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.