SpringBoot实现QQ第三方登录(最简方法)

SpringBoot实现QQ第三方登录

一、QQ第三方登录介绍

1、要实现QQ第三方登录必须在QQ互联申请第三方登录接口
2、搞第三方登录,必须先进行接口的申请并得到授权;
3、QQ第三方接口的申请地址:QQ互联 https://connect.qq.com/index.html
4、申请之前,你必须有一个进行过国内备案过的网站,个人也可以;
5、登录QQ互联后,首先填写个人或者公司信息,然后申请网站应用,但是APP的话,需要申请移动应用;
在这里插入图片描述
在这里插入图片描述

这里有个回调地址注意下,是用户进行第三方登录的时候会带上这个参数一起请求服务器,然后腾讯服务器再调用这个地址,顺便把用户信息带也过来,这样开发者的服务器就能得到用户信息了;

二、实现原理

OAuth 2.0简介

 为了简化网站和应用的注册登录开发,第三方登录横空出世,比如QQ登录,微信登录,微博登录等等;

第三方登录也叫做第三方授权,相应的规范是OAuth 2.0;每家提供第三方登录的大型互联网公司都有具体实现,原理一致,大体过程一致,细节有差别;

这里我们先了解下OAuth 2.0原理;
OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0。 OAuth 2.0关注客户端开发者的简易性。要么通过组织在资源拥有者和HTTP服务商之间的被批准的交互动作代表用户,要么允许第三方应用代表用户获得访问的权限。同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。2012年10月,OAuth2.0协议正式发布为RFC 6749 [1]

在这里插入图片描述
在认证和授权的过程中涉及的三方包括:

1、服务提供方,用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。

2、用户,存放在服务提供方的受保护的资源的拥有者。

3、客户端,要访问服务提供方资源的第三方应用,通常是网站,如提供照片打印服务的网站。在认证过程之前,客户端要向服务提供者申请客户端标识。

使用OAuth进行认证和授权的过程如下所示:

用户想操作存放在服务提供方的资源。

用户登录客户端向服务提供方请求一个临时令牌。

服务提供方验证客户端的身份后,授予一个临时令牌。

客户端获得临时令牌后,将用户引导至服务提供方的授权页面请求用户授权。在这个过程中将临时令牌和客户端的回调连接发送给服务提供方。

用户在服务提供方的网页上输入用户名和密码,然后授权该客户端访问所请求的资源。

授权成功后,服务提供方引导用户返回客户端的网页。

客户端根据临时令牌从服务提供方那里获取访问令牌。

服务提供方根据临时令牌和用户的授权情况授予客户端访问令牌。

客户端使用获取的访问令牌访问存放在服务提供方上的受保护的资源。

QQ第三方登录实现大体过程:

Step1:接入申请,获取appid和apikey;

Step2:放置QQ登录按钮;

Step3:通过用户登录验证和授权,获取Access Token;

Step4:通过Access Token获取用户的OpenID;

Step5:调用OpenAPI,来请求访问或修改用户授权的资源。

三、接口信息

get_user_info接口窥探
申请通过过,腾讯开放平台给我们提供了get_user_info接口
我们得熟悉下这个接口,通过这个接口我们能获取到一些比如昵称,性别,头像等信息;

接口概要

urlhttps://graph.qq.com/user/get_user_info
支持验证方式oauth2.0
格式JSON
http请求方式GET
是否需要鉴权需要

请求参数:

参数含义
access_token可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
oauth_consumer_key申请QQ登录成功后,分配给应用的appid,openid 用户的ID,与QQ号码一一对应。
可通过调用https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN 来获取。

请求Demo:

https://graph.qq.com/user/get_user_info?access_token=YOUR_ACCESS_TOKEN&oauth_consumer_key=YOUR_APP_ID&openid=YOUR_OPENID

返回Demo:

{ “ret”:0, “msg”:"", “nickname”:“YOUR_NICK_NAME”, … }

返回参数说明:

参数说明描述
ret返回码
msg如果ret<0,会有相应的错误信息提示,返回数据全部用UTF-8编码。
nickname用户在QQ空间的昵称。
figureurl大小为30×30像素的QQ空间头像URL。
figureurl_1大小为50×50像素的QQ空间头像URL。
figureurl_2大小为100×100像素的QQ空间头像URL。
figureurl_qq_1大小为40×40像素的QQ头像URL。
figureurl_qq_2大小为100×100像素的QQ头像URL。需要注意,不是所有的用户都拥有QQ的100x100的头像,但40x40像素则是一定会有。
gender性别。 如果获取不到则默认返回"男"

三、SpringBoot代码实现

QQ第三方登录官方提供了一个sdk for java
我们可以将其导入到本地仓库中使用
jar、源码获取地址:微信公众号搜索清峰小栈回复QQ第三方登录

关键的三步:
第一步: 获取腾讯服务器返回的accessToken;
第二步:通过accessToken获取openId;(底层分析,这步请求的是https://graph.qq.com/oauth2.0/me
接口 );
第三步:通过accessToken和openId得到用户信息;(底层分析,这步请求是https://graph.qq.com/user/get_user_info接口)
然后得到数据后 放session,放数据库 以及判断啥的 根据自己的业务来搞即可;
这里的openId是每个用户的唯一标识,所以肯定得处理好;

1、Sdk4J.jar安装到本地maven仓库
maven仓库没有提供下载坐标所以我们这里首先把Sdk4J.jar搞到本地仓库去;
为了方便,我们把Sdk4J.jar放到C:\Users\Administrator目录下;
然后cmd进入命令行
执行 mvn install:install-file -DgroupId=com.qq -DartifactId=Sdk4J -Dversion=2 -Dpackaging=jar -Dfile=Sdk4J.jar
即可;执行完,本地仓库就多了一个jar包;
在这里插入图片描述
这样才算是安装到本地仓库;

2、然后我们maven pom.xml配置导入依赖:

<!-- 第三方QQ登录 -->
<dependency>
    <groupId>com.qq</groupId>
    <artifactId>Sdk4J</artifactId>
    <version>2</version>
</dependency>

3、application.yml配置和配置文件:

server:
  port: 80
  servlet:
    context-path: /
  tomcat:
    uri-encoding: utf-8
 
 
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db_sss?serverTimezone=GMT
    username: root
    password: 123456
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    thymeleaf:
         cache: false

配置文件:
在这里插入图片描述

4、index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>QQ登录测试</title>
</head>
<body>
<div style="padding: 40px">
    <font color="black"><strong>QQ一键登录测试</strong>
    //前端只需提供一个登录QQ的请求即可
    <a href="/qqLogin"><img src="/images/qqlogin.png"/></a>
</html>

5、IndexController类:


/* * @author: 清峰
 * @date: 2020/11/28 22:43
 * @code: 愿世间永无Bug!
 * @description: qq登录控制器
 */

@Controller
public class QQController {

    @Autowired
    private QQUserService qqUserService;


    /**
     * 根目录请求
     *
     * @return
     *//*
    @RequestMapping("/")
    public ModelAndView root() {
        ModelAndView mav = new ModelAndView();
        mav.setViewName("index");
        mav.addObject("title", "QQ登录测试");
        return mav;
    }*/


    /**
     * qq登录 带参数发送服务器
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("/qqLogin")
    public void qqLogin(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setContentType("text/html;charset=utf-8");
        try {
            //底层是重定向到qq的第三方登录界面 其实重定向请求的是
            //https://graph.qq.com/oauth2.0/authorize 接口;以及封装一堆参数;
            response.sendRedirect(new Oauth().getAuthorizeURL(request));
        } catch (QQConnectException e) {
            e.printStackTrace();
        }
    }

    /**
     * 回调
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("/connect")
    public String connect(HttpServletRequest request,
                          HttpServletResponse response,
                          RedirectAttributes attributes) throws Exception {
        response.setContentType("text/html; charset=utf-8");
        try {
            //根据登录的状态获取AccessToken
            AccessToken accessTokenObj = (new Oauth()).getAccessTokenByRequest(request);
            String accessToken = null,
                    openID = null;
            long tokenExpireIn = 0L;

            if (accessTokenObj.getAccessToken().equals("")) {
//                我们的网站被CSRF攻击了或者用户取消了授权
//                做一些数据统计工作
                System.out.print("没有获取到响应参数");
            } else {
                accessToken = accessTokenObj.getAccessToken();  //授权令牌
                tokenExpireIn = accessTokenObj.getExpireIn();   //过期时间


                // 利用获取到的accessToken 去获取当前用的openid -------- start
                //通过accessToken获取openId;(底层分析,这步请求的是https://graph.qq.com/oauth2.0/me 接口 );
                //然后得到数据后 放session,放数据库 以及判断啥的 根据自己的业务来搞即可;
                //这里的openId是每个用户的唯一标识,所以肯定得处理好;
                OpenID openIDObj = new OpenID(accessToken);
                openID = openIDObj.getUserOpenID();


                //过accessToken和openId得到用户信息;(底层分析,这步请求是https://graph.qq.com/user/get_user_info接口)
                UserInfo qzoneUserInfo = new UserInfo(accessToken, openID);
                UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo();

                System.out.println("用户信息: " + userInfoBean);

                if (userInfoBean.getRet() == 0) {   //getRet() 返回状态码 0成功 0<失败
                    /*用户昵称可能带有表情解决方法参考:
                    *   修改数据库编码格式 :utf8改成了“utf8mb4”
                        将昵称进行Base64加密存储,解密输出
                        存储昵称时进行昵称判断编写过滤emoji工具
                        引入第三方依赖包:emoji-java
                    * */
                    //获取QQ昵称
                    String nickname = userInfoBean.getNickname();   //用户昵称可能带有表情,存不进数据库,对其进行转码
                    //获取QQ性别
                    String gender = userInfoBean.getGender();
                    //获取QQ头像
                    String avatar = userInfoBean.getAvatar().getAvatarURL30();

                    //这里可以做自己的业务逻辑如:将用户信息保存在数据库中
                    
                       /* request.getSession().setAttribute("demo_access_token", accessToken);
                        request.getSession().setAttribute("demo_token_expirein", String.valueOf(tokenExpireIn));
                        request.getSession().setAttribute("demo_openid", openID);*/

                } else {
                    System.out.println("很抱歉,我们没能正确获取到您的信息,原因是: " + userInfoBean.getMsg());
                }
            }
        } catch (QQConnectException e) {
        }
        return "";
    }
}
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现第三方qq登录,可以使用QQ互联提供的开放平台接口。具体的步骤如下: 1. 注册成为QQ互联开发者,并创建应用。在创建应用时,需要填写应用的基本信息,并获得AppID和AppKey。 2. 在Spring Boot后端项目中,使用Spring Security实现OAuth2认证。在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-client</artifactId> <version>5.3.4.RELEASE</version> </dependency> ``` 3. 在前端Vue项目中,使用Vue CLI创建项目,并安装vue-cli-plugin-qrcode实现生成二维码。在Terminal中运行以下命令: ``` vue create qq-login-demo cd qq-login-demo vue add qrcode ``` 4. 在Spring Boot后端项目中,实现OAuth2的配置。在application.yml文件中添加以下配置: ```yaml spring: security: oauth2: client: registration: qq: clientId: <your app id> clientSecret: <your app key> redirectUriTemplate: "{baseUrl}/login/oauth2/code/{registrationId}" authorizationUri: https://graph.qq.com/oauth2.0/authorize tokenUri: https://graph.qq.com/oauth2.0/token userInfoUri: https://graph.qq.com/user/get_user_info scope: - get_user_info provider: qq: authorizationUri: https://graph.qq.com/oauth2.0/authorize tokenUri: https://graph.qq.com/oauth2.0/token userInfoUri: https://graph.qq.com/user/get_user_info?oauth_consumer_key={clientId}&openid={oauthId} userNameAttribute: nickname ``` 5. 在前端Vue项目中,实现二维码生成。在App.vue文件中添加以下代码: ```vue <template> <div id="app"> <div v-if="!isLogin"> <qrcode :value="qrCodeUrl"></qrcode> </div> <div v-else> <p>{{ userInfo.nickname }}</p> <img :src="userInfo.figureurl_qq_1" alt="头像"> </div> </div> </template> <script> import QRCode from 'qrcode' export default { name: 'App', data() { return { isLogin: false, qrCodeUrl: '' } }, mounted() { this.generateQRCode() }, methods: { async generateQRCode() { const response = await this.$http.get('/qq-login/qr-code') if (response.status === 200) { this.qrCodeUrl = response.data this.isLogin = false } }, async checkLoginStatus() { const response = await this.$http.get('/qq-login/check-login-status') if (response.status === 200) { this.userInfo = response.data this.isLogin = true } } } } </script> ``` 6. 在Spring Boot后端项目中,实现二维码生成和登录状态检查。在QqLoginController.java文件中添加以下代码: ```java @RestController @RequestMapping("/qq-login") public class QqLoginController { private final OAuth2AuthorizedClientService authorizedClientService; private final RestTemplate restTemplate; @Autowired public QqLoginController(OAuth2AuthorizedClientService authorizedClientService, RestTemplate restTemplate) { this.authorizedClientService = authorizedClientService; this.restTemplate = restTemplate; } @GetMapping("/qr-code") public String generateQRCode() { String qrCodeUrl = "https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=<your app id>&redirect_uri=http://localhost:8080/login&state=<random state>"; try { qrCodeUrl = QRCode.from(qrCodeUrl).to(ImageType.PNG).withSize(250, 250).stream().collect(Collectors.toBase64String); } catch (WriterException | IOException e) { e.printStackTrace(); } return "data:image/png;base64," + qrCodeUrl; } @GetMapping("/check-login-status") public Map<String, Object> checkLoginStatus() { OAuth2AuthenticationToken authenticationToken = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); OAuth2AuthorizedClient authorizedClient = authorizedClientService.loadAuthorizedClient(authenticationToken.getAuthorizedClientRegistrationId(), authenticationToken.getName()); String accessToken = authorizedClient.getAccessToken().getTokenValue(); String openId = restTemplate.getForObject("https://graph.qq.com/oauth2.0/me?access_token=" + accessToken, String.class); openId = StringUtils.substringBetween(openId, "\"openid\":\"", "\"}"); Map<String, Object> userInfo = restTemplate.getForObject("https://graph.qq.com/user/get_user_info?access_token=" + accessToken + "&oauth_consumer_key=<your app id>&openid=" + openId, Map.class); return userInfo; } } ``` 7. 在前端Vue项目中,实现登录状态检查。在App.vue文件中添加以下代码: ```vue <script> export default { name: 'App', data() { return { isLogin: false, qrCodeUrl: '' } }, mounted() { this.generateQRCode() this.checkLoginStatus() setInterval(() => { this.checkLoginStatus() }, 3000) }, methods: { async checkLoginStatus() { const response = await this.$http.get('/qq-login/check-login-status') if (response.status === 200) { this.userInfo = response.data this.isLogin = true } } } } </script> ``` 至此,我们就成功地实现Spring Boot+Vue代码实现第三方QQ登录的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值