【第三方互联】三、腾讯QQ授权第三方登录

当我们创建的 QQ 互联应用成功后,我们便可以开始使用该应用来实现 QQ 互联

一、获取 APP ID 和 APP Key

1、在 QQ 互联官网首页找到“我的应用”
我的应用
2、点击应用,进入详情
获取appid和appkey
这样,我们就获取到了 APP ID 和 APP Key

二、QQ 授权登录进行开发

1、将 APP ID 、APP Key,以及该应用的信息放入项目中的配置文件中,我使用的是SpringBoot,我放在了 application.yml 配置文件中
qq互联信息

  • 二、添加 Maven 依赖,在 pom.xml 文件中,我们需要加入以下依赖信息
<!-- 网络请求 -->
<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
	<version>4.5.6</version>
</dependency>

其他依赖,请自行加入

三、登录按钮

在页面放置 QQ 授权登录的 DOM 元素

<a th:href="@{qq/auth}" class="link" title="腾讯QQ登录"><i class="layui-icon">&#xe676;</i></a>

四、接口类

创建 QQ 授权登录的 Controller,QqController.java

1、从配置文件中获取 QQ 互联信息

/**
     * QQ互联中提供的 appid 和 appkey
     */
    @Value("${qq.oauth.appid}")
    public String APPID;
    @Value("${qq.oauth.appkey}")
    public String APPKEY;
    @Value("${qq.oauth.url}")
    public String URL;

定义三个变量,接收 QQ 互联的信息

2、登录按钮点击后的接口

/**
     * 请求授权页面
     */
    @GetMapping(value = "/auth")
    public String qqAuth(HttpSession session) {
        // 用于第三方应用防止CSRF攻击
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        session.setAttribute("state", uuid);

        // Step1:获取Authorization Code
        String url = "https://graph.qq.com/oauth2.0/authorize?response_type=code" +
                "&client_id=" + APPID +
                "&redirect_uri=" + URLEncoder.encode(URL) +
                "&state=" + uuid;

        return PasswordUtils.redirectTo(url);
    }

QQ 互联的接口文档中建议我们在授权登录时传入一个加密的数据防止被攻击,我们传入了UUID,最后重定向到授权页面
QQ授权页面

3、我们在授权页面,登录了 QQ 账号,并同意授权后,就回到了我们创建应用是设置的回调地址里面了

/**
     * 授权回调
     */
    @GetMapping(value = "/callback")
    public String qqCallback(HttpServletRequest request) throws Exception {
        HttpSession session = request.getSession();
        // 得到Authorization Code
        String code = request.getParameter("code");
        // 我们放在地址中的状态码
        String state = request.getParameter("state");
        // 验证信息
        String uuid = (String) session.getAttribute("state");

        // 验证信息我们发送的状态码
        if (null != uuid) {
            // 状态码不正确,直接返回登录页面
            if (!uuid.equals(state)) {
                return PasswordUtils.redirectTo("/login");
            }
        }

        // Step2:通过Authorization Code获取Access Token
        String url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code" +
                "&client_id=" + APPID +
                "&client_secret=" + APPKEY +
                "&code=" + code +
                "&redirect_uri=" + URL;
        String access_token = QqHttpClient.getAccessToken(url);

        // Step3: 获取回调后的openID
        url = "https://graph.qq.com/oauth2.0/me?access_token=" + access_token;
        String openId = QqHttpClient.getOpenID(url);

        // Step4:获取QQ用户信息
        url = "https://graph.qq.com/user/get_user_info?access_token=" + access_token +
                "&oauth_consumer_key=" + APPID +
                "&openid=" + openId;

        // 得到用户信息
        JSONObject jsonObject = QqHttpClient.getUserInfo(url);
        /**
	     * 获取到用户信息之后,就该写你自己的业务逻辑了
	     */
        return PasswordUtils.redirectTo("/success");
    }

以上代码,从我自己的项目中拷贝而来,如果你直接使用,你需要对其业务代码进行修改

五、网络请求方法

第四步代码中所用到的网络接口方法,我放在了 QqHttpClient.java 文件中,主要有三个方法

/**
     * 获取Access Token
     */
    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;
    }

    /**
     * 获取openID
     */
    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用户信息
     */
    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;
    }
    
    /**
     * 转换json对象
     */
    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 授权登录的过程

六、总结

总结来说如图所示
qq授权登录示意图
如您在阅读中发现不足,欢迎留言!!!

下一篇:

【QQ互联】四、分享至QQ、新浪微博

©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页