SpringBoot集成QQ第三方登陆的实现

下面是关于“SpringBoot集成QQ第三方登陆的实现”的完整攻略:

准备工作

获取QQ开放平台的App ID和App Secret

在访问QQ开放平台前,需要提前获取申请QQ第三方登陆的AppID和AppSecret,具体申请过程可以参考QQ互联官方文档。

导入依赖

在SpringBoot应用的pom.xml文件中添加QQ互联API的依赖,同时可以添加日志依赖:

<dependency>
    <groupId>com.qq.connect</groupId>
    <artifactId>qq-connect-sdk</artifactId>
    <version>3.2.4</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

实现登陆逻辑

添加授权回调地址

在QQ互联开发平台上添加授权回调地址,这个地址是QQ登陆成功后返回的地址,QQ互联开发平台会根据这个地址重定向到我们的应用。

添加Controller处理授权回调请求

我们需要添加一个Controller来处理QQ登陆的授权回调请求,请求成功后,便可以获取到用户的openid。

@Controller
public class QQLoginController {
    private final Logger logger = LogManager.getLogger(QQLoginController.class);

    @Autowired
    private QQConnectAPI qqConnectAPI;

    @Autowired
    private QQOAuth2AccessTokenDao qqOAuth2AccessTokenDao;

    @GetMapping("/callback/qq")
    public String handleCallback(HttpServletRequest request, HttpServletResponse response) {
        // 获取登陆成功后的Token
        try {
            QQOAuth2AccessToken qqOAuth2AccessToken = qqConnectAPI.getAccessTokenByRequest(request);

            // 写入session
            request.getSession().setAttribute("accessToken", qqOAuth2AccessToken);

            // 根据Token获取openid
            String openId = qqConnectAPI.getOpenID(qqOAuth2AccessToken);
            logger.debug("QQ用户授权成功,openid: " + openId);

            // 重定向到首页
            return "redirect:/";
        } catch (QQConnectException e) {
            logger.error("QQ用户授权失败,异常信息: " + e.getMessage(), e);
            return null;
        }
    }

    @GetMapping("/logout")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        // 获取Token
        QQOAuth2AccessToken accessToken = (QQOAuth2AccessToken) request.getSession().getAttribute("accessToken");
        if (accessToken != null) {
            // 删除Token
            qqOAuth2AccessTokenDao.deleteByAccessToken(accessToken.getAccessToken());
            request.getSession().removeAttribute("accessToken");
            logger.debug("QQ用户退出成功");
        }
        // 重定向到首页
        return "redirect:/";
    }
}

实现QQ登陆按钮

在页面添加QQ登陆按钮,点击按钮后跳转到QQ授权界面,界面中用户需要同意授权。

<a href="https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=你的App ID&redirect_uri=http://www.example.com/callback/qq&scope=get_user_info&state=test"><img src="http://qzonestyle.gtimg.cn/qzone/vas/opensns/res/img/Connect_logo_1.png" alt="QQ授权登陆"></a>

其中,client_id是我们注册应用时获得的appid,redirect_uri跳转回调地址,scope表示要获取的用户信息,state为业务状态标识。

实现获取QQ用户信息的逻辑

添加QQAPI调用

在我们的应用中添加QQAPI的调用,获取用户信息:

@Service
public class QQConnectService {
    private final Logger logger = LogManager.getLogger(QQConnectService.class);

    @Autowired
    private QQConnectAPI qqConnectAPI;

    public void getUserInfo(QQOAuth2AccessToken accessToken) throws QQConnectException {
        QQUserInfo qqUserInfo = qqConnectAPI.getUserInfo(accessToken, "openid");
        logger.debug("QQ用户信息获取成功,信息如下: " + qqUserInfo.toString());
    }
}

添加用户信息获取逻辑

在一个Controller中添加查询用户信息的逻辑:

@Controller
public class UserController {
    private final Logger logger = LogManager.getLogger(UserController.class);

    @Autowired
    private QQConnectService qqConnectService;

    @GetMapping("/user")
    public String getUser(HttpServletRequest request) {
        // 获取用户Token
        QQOAuth2AccessToken accessToken = (QQOAuth2AccessToken) request.getSession().getAttribute("accessToken");

        if (accessToken == null) {
            logger.debug("用户未登陆,需要先通过QQ授权登陆");
            return "redirect:/";
        }

        try {
            // 获取用户信息
            qqConnectService.getUserInfo(accessToken);
            return "user";
        } catch (QQConnectException e) {
            logger.error("获取QQ用户信息失败,异常信息: " + e.getMessage(), e);
            return null;
        }
    }
}

当用户访问/user路由时,会通过Token获取QQ用户的openid,然后再通过openid获取用户的信息。

这里我们仅获取openid和用户的昵称,其他信息参照QQ官方API文档即可。

示例1:集成QQ登陆到SpringBoot应用

实现效果

这个示例实现的效果是:用户通过QQ授权登陆后,并可以通过用户信息页面获取用户的信息。

实现步骤

  1. 在QQ互联开放平台中注册应用,获取AppID和AppSecret。

  2. 添加QQAPI的依赖

在pom.xml文件中添加如下依赖:

<dependency>
    <groupId>com.qq.connect</groupId>
    <artifactId>qq-connect-sdk</artifactId>
    <version>3.2.4</version>
</dependency>
  1. 实现登陆逻辑

这里我们只需要添加QQ登陆按钮和Controller处理授权回调即可。

  1. 实现获取QQ用户信息的逻辑

添加QQAPI调用,获取用户信息,并通过Controller查询用户信息。

具体代码可以参考上面的示例。

示例2:将QQ登陆集成到已有的用户系统中

实现效果

这个示例实现的效果是:将QQ登陆集成到已有的用户系统中,用户可以通过QQ授权登陆,登陆成功后也可以注销系统登陆。

实现步骤

  1. 在现有的系统上添加QQAPI的依赖

在pom.xml文件中添加如下依赖:

<dependency>
    <groupId>com.qq.connect</groupId>
    <artifactId>qq-connect-sdk</artifactId>
    <version>3.2.4</version>
</dependency>
  1. 实现QQ授权登陆

这里我们需要添加QQ登陆按钮和Controller用于处理授权回调。

在登陆成功后,我们需要将用户的Token信息写入session,这个过程可以通过spring-session实现。

@Controller
public class QQLoginController {
    // 省略其他代码

    @GetMapping("/callback/qq")
    public String handleCallback(HttpServletRequest request, HttpServletResponse response) {
        // 获取登陆成功后的Token
        try {
            QQOAuth2AccessToken qqOAuth2AccessToken = qqConnectAPI.getAccessTokenByRequest(request);
            // 写入session
            request.getSession().setAttribute("accessToken", qqOAuth2AccessToken);
            // 根据Token获取openid
            String openId = qqConnectAPI.getOpenID(qqOAuth2AccessToken);
            logger.debug("QQ用户授权成功,openid: " + openId);

            // 将用户Token信息与现有系统中的用户账户进行绑定
            // 这里我们假设用户UserCode就是openid
            User user = userService.getByCode(openId);
            if (user == null) {
                // 如果现有系统中无此用户,则自动创建并关联
                user = new User();
                user.setCode(openId);
                user.setName(qqConnectAPI.getUserInfo(qqOAuth2AccessToken, "nickname").getNickname());

                userService.save(user);
            }

            // 绑定用户信息到session,以便于在系统中获取用户信息
            request.getSession().setAttribute("userCode", user.getCode());

            // 重定向到首页
            return "redirect:/";
        } catch (QQConnectException e) {
            logger.error("QQ用户授权失败,异常信息: " + e.getMessage(), e);
            return null;
        }
    }
}
  1. 用户信息的获取与注销

通过openid获取用户信息,以及注销token信息需要分别处理。

@Controller
public class UserController {
    private final Logger logger = LogManager.getLogger(UserController.class);

    @Autowired
    private QQConnectService qqConnectService;

    @Autowired
    private QQOAuth2AccessTokenDao qqOAuth2AccessTokenDao;

    @Autowired
    private UserService userService;

    @GetMapping("/user")
    public String getUser(HttpServletRequest request) {
        // 获取用户UserCode
        String userCode = (String) request.getSession().getAttribute("userCode");
        if (userCode == null) {
            // 如果无登陆信息,返回首页
            return "redirect:/";
        }

        // 获取QQ用户Token
        QQOAuth2AccessToken accessToken = (QQOAuth2AccessToken) request.getSession().getAttribute("accessToken");

        try {
            User user = userService.getByCode(userCode);
            // 获取用户个人信息
            QQUserInfo qqUserInfo = qqConnectService.getUserInfo(accessToken);
            user.setNickName(qqUserInfo.getNickname());

            userService.update(user);

            return "user";
        } catch (QQConnectException e) {
            logger.error("获取QQ用户信息失败,异常信息: " + e.getMessage(), e);
            return null;
        }
    }

    @GetMapping("/logout")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        // 获取Token
        QQOAuth2AccessToken accessToken = (QQOAuth2AccessToken) request.getSession().getAttribute("accessToken");
        if (accessToken != null) {
            // 删除Token
            qqOAuth2AccessTokenDao.deleteByAccessToken(accessToken.getAccessToken());
            request.getSession().removeAttribute("accessToken");
            logger.debug("QQ用户退出成功");
        }

        request.getSession().invalidate();

        // 重定向到首页
        return "redirect:/";
    }
}
  1. 其他问题

在实际应用中,可能还需要解决在系统中已有用户授权登陆的问题,或者需要为授权登录的用户创建账号密码等其他信息。这些问题需要根据具体的业务需求进行分析和实现。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot集成QQ第三方登陆的实现 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 浅谈一个基础的SpringBoot项目该包含哪些

    一个基础的SpringBoot项目应该包含以下几个部分: 1. 项目结构 一般来说,一个Spring Boot 项目的包结构应该包含三个主要部分:application、config 和 controller。 application: 启动类的所在包,在 Spring Boot 项目中只能有一个,一般放在项目的根目录下。 config: 配置类所在的包,这…

    Java 2023年5月19日
    00
  • jsp 编程之@WebServlet详解

    JSP 编程之 @WebServlet 详解 在 JavaWeb 开发中,我们经常需要编写 Servlet 来完成各种需求,而在 Servlet 3.0 版本后,推出了 @WebServlet 注解,可以更方便地编写 Servlet,并且提高了代码的可读性和可维护性。 @WebServlet 注解详解 @WebServlet 注解的作用是将一个类声明为 Se…

    Java 2023年6月15日
    00
  • java基础学习笔记之泛型

    Java基础学习笔记之泛型 简介 Java 泛型 (generics) 是 JDK 1.5 版本引入的一种数据类型,能够让程序员在编写代码时指定一些类型约束,可以更加简洁安全地使用泛型类型,提高代码的可读性和可维护性。 泛型的作用 泛型可以帮助程序员定义更加通用的代码模板,可以用来限定集合类的元素类型,避免运行时类型转换,提高程序的稳定性和效率。 泛型还可以…

    Java 2023年5月26日
    00
  • Java比较对象大小两种常用方法

    Java中比较对象大小的方式主要有两种方法,分别是 Comparable 和 Comparator 接口。 Comparable 接口比较对象大小 Comparable 接口是 Java 自带的一个接口,它定义了对象的自然顺序。如果我们需要对一个类实例进行排序或者比较大小,那么就需要让这个类实现 Comparable 接口,并重写 compareTo 方法。…

    Java 2023年5月26日
    00
  • Spring Boot2深入分析解决java.lang.ArrayStoreException异常

    问题描述: 在使用Spring Boot2开发Web应用程序过程中,有时候会遇到以下异常: java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy 这个异常可能就会使得整个应用停止工作。那么,如何分析这个异常的原因,以及如何解决它呢?下面,我会为大家…

    Java 2023年5月20日
    00
  • Java连接数据库步骤解析(Oracle、MySQL)

    Java连接数据库步骤解析(Oracle、MySQL) 在Java开发中,连接数据库是很常见的操作。这里就介绍一下Java连接Oracle和MySQL数据库的步骤。 1. Oracle数据库连接步骤 1.1 下载驱动 Java连接Oracle需要下载Oracle的JDBC驱动,下载地址如下: https://www.oracle.com/database/t…

    Java 2023年5月26日
    00
  • Java贪心算法超详细讲解

    Java贪心算法超详细讲解 什么是贪心算法 贪心算法是一种使用贪心策略的算法,它是一种在每一步选择中都采取在当前状态下最佳或最优的选择,从而导致结果是全局最优或最佳的算法思想。 与其他算法相比,贪心算法的时间复杂度一般比较低,通常来说是线性的时间复杂度,但是它的问题是不一定能够得到全局最优解。 贪心算法的步骤 贪心算法的步骤如下: 确定问题的最优子结构 设计…

    Java 2023年5月19日
    00
  • 一分钟入门Java Spring Boot彻底解决SSM配置问题

    下面我来详细讲解一下“一分钟入门Java Spring Boot彻底解决SSM配置问题”的完整攻略。 简介 Java Spring Boot是一个基于Spring Framework的快速开发框架,它可以简化Spring应用开发过程,在保持Spring优点的同时去除了其缺点。Spring Boot提供了一种快速配置、轻量级的应用开发方式,开发者只需要少量的配…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部