在我们的项目开发中,使用第三方登录(如QQ登录、微信登录等)可以更加方便、轻松地实现用户登录。

在以往的开发过程中,如果要使项目实现第三方登录功能,一般过程是阅读官网的开发文档,并下载其JDK(或者依赖pom),然后进行开发实现。

但是,如果网站要实现多个第三方平台的登录功能,则需要很高的学习成本

所以,就有开发者实现了一款基于Spring Boot的开箱即用的整合第三方登录的开源组件:JustAuth

该插件的网址:https://justauth.wiki

本文将基于Spring Boot,使用JustAuth组件实现第三方快捷登录,并获取用户的uid。

1. 插件简介

首先给出几个链接:

  • 组件的帮助文档:https://justauth.wiki
  • 组件的GitHub:https://github.com/justauth/JustAuth
  • 组件的Gitee组织:https://gitee.com/justauth/

在组件的各个网址,都可以看到关于该组件的自述:

小而全而美的第三方登录开源组件。目前已支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、企业微信、酷家乐、Gitlab、美团、饿了么和推特等第三方平台的授权登录。 Login, so easy!

可以看出,此组件支持的第三方登录平台,是非常全的。

下面,以QQ微博为例,测试Spring Boot上使用该组件完成第三方登录快速开发。

  • 建议参考组件的帮助文档,均有详细说明。
  • 或者直接参考官方的demo:https://github.com/justauth/JustAuth-demo
  • 开发之前,需要前往QQ开放平台微博开放平台申请应用,并获取 appidAPP secret ,设置callback url。参考:
    • https://blog.csdn.net/cxh_1231/article/details/114984731
    • https://blog.csdn.net/cxh_1231/article/details/115068413

2. 项目创建与导包

关于Spring Boot项目如何创建,可参考以下几篇文章:

  • Idea创建Spring Boot项目
  • Spring Boot 常用配置
  • Spring Boot整合Thymeleaf

只看前两个就可以了。

创建完成项目之后,在pom.xml文件中,导入依赖:

        <!--JustAuth--><dependency><groupId>me.zhyd.oauth</groupId><artifactId>JustAuth</artifactId><version>1.15.9</version></dependency><!--http请求相关--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-http</artifactId><version>5.3.9</version></dependency><!--导入lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency><!--fastjson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.62</version></dependency>

这里导入了4个依赖,说明如下:

第一个是JustAuth组件必须的,版本就默认使用帮助文档中的最新版,如下图所示。

第二个是http请求的实现组件,这是因为JustAuth从 v1.14.0开始不会默认集成hutool-http,需要单独添加;

第三个是lombok,即自动生成模型的setget。因为项目中授权登录成功后,返回的用户信息模型,使用了@Getter@Setter注解。添加此组件,方便获取用户的单个信息(如uuid、nickname等)。

第四个是阿里巴巴的fastjson 组件,因为在返回的结果中,有些信息是封装成 JSON格式 的,需要使用该组件来转换成 map键值对 ,从而获取对我们有用的信息。

3. QQ登录实现

1、 新建一个名为 PluginController 的控制类,用来实现第三方插件的登录回调功能。

package com.demo.controller;import org.springframework.web.bind.annotation.*;/*** Info:登录组件测试** @author: 拾年之璐* @date: 2021-03-15 0015 19:27*/
@RestController
@RequestMapping(value = "/plugin")
public class PluginController {}

2、创建一个AuthRequest接口的实现类,用于生成登录链接登录并获取用户信息

    /*** 授权接口类** @return 各种请求的结果*/private AuthRequest getQQAuthRequest() {return new AuthQqRequest(AuthConfig.builder().clientId("APPID").clientSecret("Your APP Secret").redirectUri("http://XXX.com/plugin/qqlogin/callback").unionId(true) //如果获取用户的UnionID,则设置为true.build());}

3、生成登录链接跳转至登录页面

    /*** 跳转至登录页面** @param response 页面跳转* @throws IOException*/@RequestMapping("/qqlogin")public void qqlogin(HttpServletResponse response) throws IOException {//获取对象AuthRequest authRequest = getQQAuthRequest();//打印生成的链接System.out.println("生成登录链接:" + authRequest.authorize("yourState"));//页面跳转,其中state参数可自定义response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));}

这时,控制台可以打印出生成的登录URL

浏览器访问http://XXX.com/plugin/qqlogin,即可跳转至此登录页面

4、回调页面plugin/qqlogin/callback获取返回的code,并通过返回的code获取当前登录用户的信息

如下:

   /*** QQ登录成功后返回到此页** @param callback 登录用户的信息* @return*/@RequestMapping("/qqlogin/callback")public Object qqloginCallback(AuthCallback callback) {AuthRequest authRequest = getQQAuthRequest();// 打印返回的授权信息(QQ登录为code,通过code获取用户信息)System.out.println(callback.getCode());//根据返回的参数,执行登录请求(获取用户信息)AuthResponse<AuthUser> authResponse = authRequest.login(callback);// 将JSON包返回到前端页面显示return authResponse;}

上面的图,点击登录后,即可跳转至回调页面,显示出所有的JSON数据,如下图所示:

我们对该JSON数据进行分析:

  • 返回的code是2000,表示获取数据成功(其他代码,可以在https://justauth.wiki/quickstart/error_code.html查看);
  • 返回的data数据,包含所有有用的信息,如用户IDuuid、用户昵称username、头像avatar、性别gender等等;
  • data下的token,包含所有的获取token刷新token过期时间等信息;
  • data下rawUserInfo,是第三方平台返回的原始用户信息
  • 关于返回的JSON数据的每个子段的详细含义,都可以在模型AuthUser中查看。

5、后台获取指定信息

上面可以获取所有的用户信息,但这些信息,我们并不能这样使用,而是筛选有用的信息,然后保存到自己的数据库。

所以下面这个完整示例,演示如何获取上述JSON中的指定信息。

  /*** QQ登录成功后返回到此页** @param callback 登录用户的信息* @return*/@RequestMapping("/qqlogin/callback")public Object qqloginCallback(AuthCallback callback) {//获取实例AuthRequest authRequest = getQQAuthRequest();// 打印返回的授权信息(QQ登录为code,通过code获取用户信息)System.out.println(callback.getCode());//根据返回的参数,执行登录请求(获取用户信息)AuthResponse<AuthUser> authResponse = authRequest.login(callback);//打印授权返回代码(2000 表示成功,可以用来判断用户登录成功与否)System.out.println("状态码:"+authResponse.getCode());//打印用户的昵称、ID、头像等基本信息System.out.println("用户的UnionID:" + authResponse.getData().getUuid());System.out.println("用户的昵称:" + authResponse.getData().getNickname());System.out.println("用户的头像:" + authResponse.getData().getAvatar());//打印用户的Token中的信息System.out.println("access_token:" + authResponse.getData().getToken().getAccessToken());System.out.println("用户的OpenId:" + authResponse.getData().getToken().getOpenId());// 打印更加详细的信息(第三方平台返回的原始用户信息)//getInnerMap():将JSONObject转换成Map键值对System.out.println("用户的城市:" + authResponse.getData().getRawUserInfo().getInnerMap().get("city"));System.out.println("用户的年份:" + authResponse.getData().getRawUserInfo().getInnerMap().get("year"));// 将JSON包返回到前端页面显示return authResponse;}

其实这段代码,和JSON数据,是一一对应的,如下图所示:

打印结果:

4. 微博登录实现

有了上面QQ登录的详细分析,微博登录也是类似的,这里速战速决。

1、创建授权请求类

    /*** 生成微博授权登录的类getWbAuthRequest** @return*/private AuthRequest getWbAuthRequest() {return new AuthWeiboRequest(AuthConfig.builder().clientId("appid").clientSecret("app secret").redirectUri("http://xxx.com/plugin/sinalogin/callback").build());}

2、生成并跳转登录链接

   /*** 微博登录页面,生成登录链接** @param response 页面跳转* @throws IOException*/@RequestMapping("/wblogin")public void wblogin(HttpServletResponse response) throws IOException {//生成对象AuthRequest authRequest = getWbAuthRequest();//生成链接并返回,其中state可以自定义,可以用来实现第四方登录response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));}

结果:

3、回调页面获取信息,以及返回JSON数据

    /*** 回调页面,获取登录用户新** @param callback 详细JSON信息* @return*/@RequestMapping("/sinalogin/callback")public Object wbloginCallback(AuthCallback callback) {//生成对象AuthRequest authRequest = getWbAuthRequest();//获取登录后返回的用户信息结果AuthResponse<AuthUser> authResponse = authRequest.login(callback);//打印授权返回代码(2000 表示成功,可以用来判断用户登录成功与否)System.out.println("状态码:" + authResponse.getCode());//打印用户的昵称、ID、头像等基本信息System.out.println("用户的UnionID:" + authResponse.getData().getUuid());System.out.println("用户的昵称:" + authResponse.getData().getNickname());System.out.println("用户的头像:" + authResponse.getData().getAvatar());//打印用户的Token中的信息System.out.println("access_token:" + authResponse.getData().getToken().getAccessToken());System.out.println("用户的OpenId:" + authResponse.getData().getToken().getOpenId());// 打印更加详细的信息(第三方平台返回的原始用户信息)System.out.println("用户的城市:" + authResponse.getData().getRawUserInfo().getInnerMap().get("city"));System.out.println("用户的年份:" + authResponse.getData().getRawUserInfo().getInnerMap().get("year"));//返回JSON信息return authResponse;}

结果:

5. 完整Controller源码

package com.demo.controller;import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthQqRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.request.AuthWeiboRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** Info:登录组件测试** @author: 拾年之璐* @date: 2021-03-22 0022 19:31*/
@RestController
@RequestMapping(value = "/plugin")
public class PluginController {/*** QQ登录request类** @return 链接*/private AuthRequest getQQAuthRequest() {return new AuthQqRequest(AuthConfig.builder().clientId("appid").clientSecret("appsecret").redirectUri("http://xxx.com/plugin/qqlogin/callback").unionId(true).build());}/*** 跳转至登录页面** @param response 页面跳转* @throws IOException*/@RequestMapping("/qqlogin")public void qqlogin(HttpServletResponse response) throws IOException {//获取实例AuthRequest authRequest = getQQAuthRequest();//打印生成的链接System.out.println("生成登录链接:" + authRequest.authorize("yourState"));System.out.println();//页面跳转,其中state参数可自定义response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));}/*** QQ登录成功后返回到此页** @param callback 登录用户的信息* @return*/@RequestMapping("/qqlogin/callback")public Object qqloginCallback(AuthCallback callback) {//获取实例AuthRequest authRequest = getQQAuthRequest();// 打印返回的授权信息(QQ登录为code,通过code获取用户信息)System.out.println(callback.getCode());//根据返回的参数,执行登录请求(获取用户信息)AuthResponse<AuthUser> authResponse = authRequest.login(callback);//打印授权返回代码(2000 表示成功,可以用来判断用户登录成功与否)System.out.println("状态码:" + authResponse.getCode());//打印用户的昵称、ID、头像等基本信息System.out.println("用户的UnionID:" + authResponse.getData().getUuid());System.out.println("用户的昵称:" + authResponse.getData().getNickname());System.out.println("用户的头像:" + authResponse.getData().getAvatar());//打印用户的Token中的信息System.out.println("access_token:" + authResponse.getData().getToken().getAccessToken());System.out.println("用户的OpenId:" + authResponse.getData().getToken().getOpenId());// 打印更加详细的信息(第三方平台返回的原始用户信息)System.out.println("用户的城市:" + authResponse.getData().getRawUserInfo().getInnerMap().get("city"));System.out.println("用户的年份:" + authResponse.getData().getRawUserInfo().getInnerMap().get("year"));// 将JSON包返回到前端页面显示return authResponse;}/*** 生成微博授权登录的类getWbAuthRequest** @return*/private AuthRequest getWbAuthRequest() {return new AuthWeiboRequest(AuthConfig.builder().clientId("appid").clientSecret("appsecret").redirectUri("http://xxx.com/plugin/sinalogin/callback").build());}/*** 微博登录页面,生成登录链接** @param response 页面跳转* @throws IOException*/@RequestMapping("/wblogin")public void wblogin(HttpServletResponse response) throws IOException {//生成对象AuthRequest authRequest = getWbAuthRequest();//生成链接并返回,其中state可以自定义,可以用来实现第四方登录response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));}/*** 回调页面,获取登录用户新** @param callback 详细JSON信息* @return*/@RequestMapping("/sinalogin/callback")public Object wbloginCallback(AuthCallback callback) {//生成对象AuthRequest authRequest = getWbAuthRequest();//获取登录后返回的用户信息结果AuthResponse<AuthUser> authResponse = authRequest.login(callback);//打印授权返回代码(2000 表示成功,可以用来判断用户登录成功与否)System.out.println("状态码:" + authResponse.getCode());//打印用户的昵称、ID、头像等基本信息System.out.println("用户的UnionID:" + authResponse.getData().getUuid());System.out.println("用户的昵称:" + authResponse.getData().getNickname());System.out.println("用户的头像:" + authResponse.getData().getAvatar());//打印用户的Token中的信息System.out.println("access_token:" + authResponse.getData().getToken().getAccessToken());System.out.println("用户的OpenId:" + authResponse.getData().getToken().getOpenId());// 打印更加详细的信息(第三方平台返回的原始用户信息)System.out.println("用户的城市:" + authResponse.getData().getRawUserInfo().getInnerMap().get("city"));System.out.println("用户的年份:" + authResponse.getData().getRawUserInfo().getInnerMap().get("year"));//返回JSON信息return authResponse;}/*** 销毁*/@RequestMapping("/revoke/{token}")public Object revokeAuth(@PathVariable("token") String token) throws IOException {AuthRequest authRequest = getWbAuthRequest();return authRequest.revoke(AuthToken.builder().accessToken(token).build());}}

当然,还有其他各个平台,如:

每个平台的授权登录实现方式大同小异,此处不再赘述。

参考资料:

  1. https://justauth.wiki/quickstart/explain.html
  2. https://justauth.wiki/oauth/qq.html
  3. https://justauth.wiki/oauth/weibo.html

Spring Boot开发之使用JustAuth组件实现第三方登录(QQ、微博等)相关推荐

  1. springboot thymeleaf配置_【程序源代码】Spring Boot 开发笔记web开发实战1

    关键字:<Spring Boot 开发笔记>系列文章 各位亲爱的小伙伴:大家好! <Spring Boot 开发笔记>系列文章 这套笔记和源码是我自己在学习springboot ...

  2. Spring Boot开发介绍

    Spring Boot开发介绍 Spring Boot介绍 安装Spring Boot插件 创建Spring Boot项目 Idea 创建Spring Boot项目失败 解决方法1-更换为aliyun ...

  3. 真的简单,单手用Spring Boot 开发一个微信小程序

    前言   嗨,大家好,现在微信使用的用户很多,作为开发人员也可以建立一个自己的微信小程序,本期与大家分享一下作者建立微信小程序的开发流程. 申请   百度搜索微信公众号平台,然后扫码登录注册一个微信公 ...

  4. 保姆级的一个基于spring boot开发的前后端分离商城教程

    前言 推荐一个基于spring boot开发前后端分离商城,有完整的代码笔记和视频教程,希望对正在找项目练手的同学有所帮助 本文资料文档领取(在文末) 一.项目背景 5中常见的电商模式 B2B .B2 ...

  5. 《Spring Boot开发:从0到1》大纲结构

    <Spring Boot开发:从0到1> 大纲结构v2.0 第一部分Spring Boot基础 第1章 Spring Boot史前简述 1.1 J2EE(Java 2 Platform E ...

  6. 【直播回顾】云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第19讲):Java Spring Cloud微服务架构模式与开发实战...

    主讲人:徐雷(云栖社区特邀Java专家) 徐雷,花名:徐雷frank:资深架构师,MongoDB中文社区联席主席,吉林大学计算机学士,上海交通大学硕士.从事了 10年+开发工作,专注于分布式架构,Ja ...

  7. 开源oa_圈子哥推荐一款基于 Spring Boot 开发 OA 开源产品,学习/搞外快都是不二选择!...

    点击上方蓝字关注「程序员的技术圈子」 今天圈子哥给大家推荐一套Spring Boot 开发 OA系统,系统功能齐全,不管是用来学习或者搞外快都是不错的选择,clone下来吧! 办公自动化(OA)是面向 ...

  8. 从零搭建一个 Spring Boot 开发环境!Spring Boot+Mybatis+Swagger2 环境搭建

    从零搭建一个 Spring Boot 开发环境!Spring Boot+Mybatis+Swagger2 环境搭建 本文简介 为什么使用Spring Boot 搭建怎样一个环境 开发环境 导入快速启动 ...

  9. 计算机网络即时通信系统设计_天天玩微信,Spring Boot 开发私有即时通信系统了解一下...

    概述 利用Spring Boot作为基础框架,Spring Security作为安全框架,WebSocket作为通信框架,实现点对点聊天和群聊天. 所需依赖 Spring Boot 版本 1.5.3, ...

最新文章

  1. 10分钟内基于gpu的目标检测
  2. 2019 ICPC Asia Nanjing Regional C.Digital Path(拓扑排序递推DP)
  3. 使用Lucene分词
  4. python基础代码库-python基础知识和练习代码
  5. Redis set 类型操作及常用命令
  6. 企业中的微服务:敌是友?
  7. java兔子问题流程图_C语言编程狼追兔子问题代码解析
  8. 将强化学习应用到量化投资中实战篇(学习模块开发上)
  9. kali Linux 工具 BurpSuite-暴力破解
  10. Blender - Shrinkwrap - 更方便的制作贴合模型的表面来建模
  11. 【LeetCode-769. medium】最多能完成排序的块
  12. 用74ls90组成二十四进制计数器_一个厉害的芯片芯片74LS190同步计数器可以做加法也可以做减法...
  13. 阿里云服务器安装oracle11g——会用的到,建议收藏
  14. 鸿蒙系统需要备份,华为鸿蒙系统正式发布之后,还需要面临三个问题
  15. Microsoft SQL Server 2000 Service Pack 3a
  16. 「凹凸数据」历史文章合集,更新中
  17. 【Jenkins】win 10 / win 11:Jenkins 的下载、安装、部署(Jenkins 2.365 基于 Java 17)
  18. 单片机嵌入式二维码解码识别
  19. 恒州诚思——2022-2028全球硫酸镱行业调研及趋势分析报告
  20. day02 智能合约

热门文章

  1. 超级直播对接骆驼后台IPTV管理,只精简保留和修改TV相关的后台,骡马TV
  2. 【题解】展翅翱翔之时 (はばたきのとき)
  3. [机缘参悟-13]:菩提心,一切“利他”之心
  4. 未来5年到底是做什么生意最好?
  5. luogu3755 [CQOI2017]老C的任务
  6. 中国移动,电信,联通,铁通,网通的区别与联系
  7. 直销银行和网上银行区别
  8. 对学术不怎么热爱,只想当大学老师而去读博可以么?
  9. 学术数据库---EI
  10. 洛谷 P2884 【[USACO07MAR]每月的费用Monthly Expense】