Implementing QQ login in java

Keywords: Session Apache Java JSON

Links to the original text: https://blog.csdn.net/qq_37618797/article/details/90344835

--------
Forwarding Statement: This article is reprinted to the CSDN blogger "Drunk Three Lives". It is reprinted to the CSDN blogger.
Links to the original text: https://blog.csdn.net/qq_37618797/article/details/90344835

I. Preparations

1. Cloud Server

2. Domain name for filing

3. Local debugging needs to modify hosts files to map domain names to 127.0.0.1
First, apply for QQ interconnection and become a developer

QQ interconnection: https://connect.qq.com/index.html

After login, click on the avatar, enter the authentication page, fill in the information, and wait for review.


After approval, click Create Application

After the audit is approved, you can use APP ID and APP Key

2. Writing java code

github:https://github.com/sansheng741/QQLogin

Project structure

yml configuration

server:
  port: 80
 
qq:
  oauth:
    http: //Website Address Filled in QQ Interconnection

Importing pom dependencies

<!--httpclient-->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.6</version>
</dependency>
<!--Ali JSON-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>

QQController

package com.ck.blog.controller;
 
import com.alibaba.fastjson.JSONObject;
import com.ck.blog.exception.StateErrorException;
import com.ck.blog.utils.QQHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.URLEncoder;
import java.util.UUID;
 
/**
 * @author ck
 * @create 2019-05-18 20:32
 */
@Controller
public class QQController {
 
 
    @Value("${qq.oauth.http}")
    private String http;
 
    /**
     * Initiate request
     * @param session
     * @return
     */
    @GetMapping("/qq/oauth")
    public String qq(HttpSession session){
        //Callback Address in QQ Interconnection
        String backUrl = http + "/qq/callback";
 
        //Preventing CSRF attacks for third-party applications
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        session.setAttribute("state",uuid);
 
        //Step1: Get Authorization Code
        String url = "https://graph.qq.com/oauth2.0/authorize?response_type=code"+
                "&client_id=" + QQHttpClient.APPID +
                "&redirect_uri=" + URLEncoder.encode(backUrl) +
                "&state=" + uuid;
 
        return "redirect:" + url;
    }
 
    /**
     * QQ Callback
     * @param request
     * @return
     */
    @GetMapping("/qq/callback")
    public String qqcallback(HttpServletRequest request) throws Exception {
        HttpSession session = request.getSession();
        //Information returned by qq: http://graph.qqq.com/demo/index.jsp?Code=9A5F**************************************************** 06AF&state=test
        String code = request.getParameter("code");
        String state = request.getParameter("state");
        String uuid = (String) session.getAttribute("state");
 
        if(uuid != null){
            if(!uuid.equals(state)){
                throw new StateErrorException("QQ,state error");
            }
        }
 
 
        //Step2: Get Access Token through Authorization Code
        String backUrl = http + "/qq/callback";
        String url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code"+
                "&client_id=" + QQHttpClient.APPID +
                "&client_secret=" + QQHttpClient.APPKEY +
                "&code=" + code +
                "&redirect_uri=" + backUrl;
 
        String access_token = QQHttpClient.getAccessToken(url);
 
        //Step3: Get the openid value after the callback
        url = "https://graph.qq.com/oauth2.0/me?access_token=" + access_token;
        String openid = QQHttpClient.getOpenID(url);
 
        //Step4: Getting QQ user information
        url = "https://graph.qq.com/user/get_user_info?access_token=" + access_token +
                "&oauth_consumer_key="+ QQHttpClient.APPID +
                "&openid=" + openid;
 
        JSONObject jsonObject = QQHttpClient.getUserInfo(url);
 
        //You can also put it in Redis and mysql
        session.setAttribute("openid",openid);  //openid, used to uniquely identify qq users
        session.setAttribute("nickname",(String)jsonObject.get("nickname")); //QQ name
        session.setAttribute("figureurl_qq_2",(String)jsonObject.get("figureurl_qq_2")); //QQ header URL with 100*100 pixels in size
 
 
        return "redirect:/home";
    }
 
}

QQHttpClient

package com.ck.blog.utils;
 
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
 
import java.io.IOException;
 
/**
 * @author ck
 * @create 2019-05-18 20:32
 * QQ Tool class (mainly for parsing information returned by QQ)
 */
public class QQHttpClient {
    //appid and appkey provided in QQ interconnection
    public static final String APPID = "xxxxxxxx";
 
    public static final String APPKEY = "xxxxxxxxxx";
 
 
    private static JSONObject parseJSONP(String jsonp){
        int startIndex = jsonp.indexOf("(");
        int endIndex = jsonp.lastIndexOf(")");
 
        String json = jsonp.substring(startIndex + 1,endIndex);
 
        return JSONObject.parseObject(json);
    }
    //qq return information: access_token = FE04******************************************************** CCE2 & expires_in = 7776000 & refresh_token = 88E4****************************** BE14
    public static String getAccessToken(String url) throws IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        String token = null;
 
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
 
        if(entity != null){
            String result = EntityUtils.toString(entity,"UTF-8");
            if(result.indexOf("access_token") >= 0){
                String[] array = result.split("&");
                for (String str : array){
                    if(str.indexOf("access_token") >= 0){
                        token = str.substring(str.indexOf("=") + 1);
                        break;
                    }
                }
            }
        }
 
        httpGet.releaseConnection();
        return token;
    }
    //qq returns information: callback ({"client_id": "YOUR_APPID", "openid": "YOUR_OPENID"}); parseJSONP, the parsing method defined above, needs to be used.
    public static String getOpenID(String url) throws IOException {
        JSONObject jsonObject = null;
        CloseableHttpClient client = HttpClients.createDefault();
 
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
 
        if(entity != null){
            String result = EntityUtils.toString(entity,"UTF-8");
            jsonObject = parseJSONP(result);
        }
 
        httpGet.releaseConnection();
 
        if(jsonObject != null){
            return jsonObject.getString("openid");
        }else {
            return null;
        }
    }
    
    //qq returns information: {"ret":0,""msg":", "nickname", "YOUR_NICK_NAME",...} in JSON format, parsed directly using JSONObject objects
    public static JSONObject getUserInfo(String url) throws IOException {
        JSONObject jsonObject = null;
        CloseableHttpClient client = HttpClients.createDefault();
 
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
 
 
        if(entity != null){
            String result = EntityUtils.toString(entity,"UTF-8");
            jsonObject = JSONObject.parseObject(result);
        }
 
        httpGet.releaseConnection();
 
        return jsonObject;
    }
}

IndexController

package com.ck.blog.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
 
import javax.servlet.http.HttpSession;
 
/**
 * @author ck
 * @create 2019-05-18 20:31
 */
@Controller
public class IndexController {
 
    @GetMapping("/index")
    public String index(){
        return "index";
    }
 
    @GetMapping("/home")
    public String home(HttpSession session, Model model){
        String openid = (String) session.getAttribute("openid");
        String nickname = (String) session.getAttribute("nickname");
        String figureurl_qq_2 = (String) session.getAttribute("figureurl_qq_2");
 
        model.addAttribute("openid",openid);
        model.addAttribute("nickname",nickname);
        model.addAttribute("figureurl_qq_2",figureurl_qq_2);
 
        return "home";
    }
}

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Login page</title>
</head>
<body>
<a href="/qq/oauth">QQ Authorized login</a>
</body>
</html>

home.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>QQ Authorized success</title>
</head>
<body>
<div>
    openid:[[${openid}]]
</div>
<div>
    nickName:[[${nickname}]]
</div>
<div>
    <img th:src="${figureurl_qq_2}">
</div>
</body>
</html>

Design sketch

Posted by DeadDude on Tue, 08 Oct 2019 10:10:15 -0700