Spring Boot整合OAuth2实现GitHub第三方登录
Spring Boot整合OAuth2,实现GitHub第三方登录
1、第三方登录原理
第三方登录的原理是借助OAuth授权来实现,首先用户先向客户端提供第三方网站的数据证明自己的身份获取授权码,然后客户端拿着授权码与授权服务器建立连接获得一个Access Token,之后客户端就可以通过Access Token来与资源服务器进行交互。
使用OAuth的好处是提供给用户一个特定的密钥,用户持有这个密钥可以访问应用中的任何信息,而不需要向网站提供用户名&密码,可以实现跨系统共享用户授权协议。
通过控制用户持有的密钥,可以很方便的控制用户可以访问的资源,以及控制密钥的过期时间。
以下是来自维基百科对于OAuth的介绍
开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。
OAuth是OpenID的一个补充,但是完全不同的服务。
交互流程如下:

2、GitHub实现第三方登录
首先需要在github中对应用进行登记,让Github知道谁在发送请求。
访问这个网址,填写登记表

提交成功之后,GitHub会返回Client ID & Client Secrets ,这是应用的身份识别码

创建一个SpringBoot工程,pom.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.17</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>org.pp</groupId><artifactId>springboot-oauth2-api</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-oauth2-api</name><description>springboot整合oauth2,实现GitHub第三方登录</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
将ID和密钥添加到配置文件application.yml中:
# 项目端口号
server:port: 8080
# GitHub认证相关参数
github:client:id: xxxsecret: xxx
创建一个实体类,用于映射授权成功产生的Token令牌:
import com.fasterxml.jackson.annotation.JsonProperty;
/**** Token令牌 - 响应参数** @author supanpan* @date 2023/10/25*/
public class AccessTokenResponse {@JsonProperty("access_token")private String accessToken;public String getAccessToken() {return accessToken;}public void setAccessToken(String accessToken) {this.accessToken = accessToken;}
}
OAuthController如下:
*** @author supanpan* @date 2023/10/25*/
@Controller
public class OAuthController {@Value("${github.client.id}")private String clientId;@Value("${github.client.secret}")private String clientSecret;@GetMapping("/oauth/redirect")public String handleRedirect(@RequestParam("code") String requestToken, Model model) {// 使用RestTemplate来发送HTTP请求RestTemplate restTemplate = new RestTemplate();// 获取Token的UrlString tokenUrl = "https://github.com/login/oauth/access_token" +"?client_id=" + clientId +"&client_secret=" + clientSecret +"&code=" + requestToken;// 使用restTemplate向GitHub发送请求,获取TokenAccessTokenResponse tokenResponse = restTemplate.postForObject(tokenUrl, null, AccessTokenResponse.class);// 从响应体中获取Token数据String accessToken = tokenResponse.getAccessToken();// 携带Token向GitHub发送请求String apiUrl = "https://api.github.com/user";HttpHeaders headers = new HttpHeaders();headers.set("Authorization", "token " + accessToken);HttpEntity<String> entity = new HttpEntity<>("parameters", headers);ResponseEntity<String> response = restTemplate.exchange(apiUrl, HttpMethod.GET, entity, String.class);model.addAttribute("userData", response.getBody());return "welcome";}
}
SpringBoot启动器
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringbootOauth2ApiApplication {public static void main(String[] args) {SpringApplication.run(SpringbootOauth2ApiApplication.class, args);}}
还需要编写两个html页面,index.html和welcome.html
index.html
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>OAuth2 Demo</title><meta name="viewport" content="width=device-width, initial-scale=1">
</head><body>
<a id="login">Login with GitHub</a><script>const client_id = 'xxxx';const authorize_uri = 'https://github.com/login/oauth/authorize';const redirect_uri = 'http://localhost:8080/oauth/redirect';const link = document.getElementById('login');link.href = `${authorize_uri}?client_id=${client_id}&redirect_uri=${redirect_uri}`;
</script></body></html>
welcome.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Hello</title>
</head><body><h1>Welcome</h1><div th:text="${userData}"></div>
</body></html>
启动项目,浏览器访问localhost:8080,会跳转到index页面,点击链接会跳转到GitHub应用授权页面
点击跳转到GitHub授权之后,GitHub会询问示例代码正在请求数据,您是否同意授权。

用户同意授权, GitHub 就会跳转到redirect_uri指定的跳转网址,并且带上授权码,跳转回来的 URL 就是下面的样子
// code参数就是授权码
http://localhost:8080/oauth/redirect?code:4ea423f2ec1e04c6376a
如下是服务的响应数据:
access token: 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
{login: 'AtwoodPa',id: 110728122,node_id: 'U_kgDOBpmTug',avatar_url: 'https://avatars.githubusercontent.com/u/110728122?v=4',gravatar_id: '',url: 'https://api.github.com/users/AtwoodPa',html_url: 'https://github.com/AtwoodPa',followers_url: 'https://api.github.com/users/AtwoodPa/followers',following_url: 'https://api.github.com/users/AtwoodPa/following{/other_user}',gists_url: 'https://api.github.com/users/AtwoodPa/gists{/gist_id}',starred_url: 'https://api.github.com/users/AtwoodPa/starred{/owner}{/repo}',subscriptions_url: 'https://api.github.com/users/AtwoodPa/subscriptions',organizations_url: 'https://api.github.com/users/AtwoodPa/orgs',repos_url: 'https://api.github.com/users/AtwoodPa/repos',events_url: 'https://api.github.com/users/AtwoodPa/events{/privacy}',received_events_url: 'https://api.github.com/users/AtwoodPa/received_events',type: 'User',site_admin: false,name: null,company: null,blog: '',location: null,email: null,hireable: null,bio: null,twitter_username: null,public_repos: 6,public_gists: 0,followers: 0,following: 3,created_at: '2022-08-06T13:02:16Z',updated_at: '2023-09-03T00:15:55Z'
}
authorization code: 4ea423f2ec1e04c6376a
成功执行上述流程,最终展示示例的welcome页面

到这里,Spring Boot整合GitHub实现第三方登录的实现就结束了,以此类推其他厂商的第三方登录实现流程也大概是这样。
相关文章:
Spring Boot整合OAuth2实现GitHub第三方登录
Spring Boot整合OAuth2,实现GitHub第三方登录 1、第三方登录原理 第三方登录的原理是借助OAuth授权来实现,首先用户先向客户端提供第三方网站的数据证明自己的身份获取授权码,然后客户端拿着授权码与授权服务器建立连接获得一个Access Token…...
Android [SPI,AutoSerivce,ServiceLoader]
记录一下在Android中使用SPI的过程。 1.项目gralde文件。 plugins {id kotlin-kapt } dependencies {implementation com.google.auto.service:auto-service:1.0-rc7 kapt "com.google.auto.service:auto-service:1.0-rc7" } 这个AutoServ…...
【Linux】ASCII码表-256个
ASCII码简介: ASCII码 是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646 。在这个页面,你可以找到8位的256个字符、ASCII码表和Windows-1252 (code page 1252,它是国际标准ISO 8859-1的一个扩展字符集) 标准保持一致;ASCII码 是 A…...
node.js - 上传文件至阿里云oss
deploy.js const fs require(fs) const path require(path) const util require(util) const OSS require(ali-oss)/*因为,在Node.js中,许多核心模块的函数都是采用回调函数的形式进行异步操作的,即在操作完成后调用回调函数来处理结果。…...
xxl-job项目集成实战,全自动项目集成,可以直接使用到项目中
如果你看官方文档,在研究透,至少也得几天时间,如果你直接看我的文档,快速用到项目中,也就10分钟就搞好了。 xxl-job功能确实很强大,而且使用的人比较多,既然在使用xxl-job,那肯定是…...
Qt生成PDF报告
文章目录 一、示意图二、实现部分代码总结 一、示意图 二、实现部分代码 //! 生成测试报告 void MainWindow::createPdf(QString filename, _pdf_msg_& msg, const QMap<QString, int>& ok, const QMap<QString, int>& err) {//QDir dir;if(!dir.exis…...
Jenkins 安装全攻略:从入门到精通
目录 一:安装文件夹准备 1.打开,/home/admin目录 2.新建三个文件夹 二:安装tomcat 1.打开tomcat目录进行tomcat安装 2.解压tomcat文件 3.开放端口号 4.启动tomcat 5.浏览器访问tomcat 三:安装Maven 1.打开maven目录进行…...
迎重阳,话养老:平安养老险如何助力国民“养老梦”?
10月23日,我们将迎来传统节日重阳节,又称敬老节,自古就有祭祖、登高、赏菊三大风俗,流传至今,已成为人们孝老敬老的重要节日。 随着老龄化日益加深,在“敬老”的同时如何“备老”成为人民群众长期热议的话题…...
微信小程序获取用户信息
个人博客 微信小程序获取用户信息 个人微信公众号,求关注,求收藏,求指错。 文章概叙 本文主要讲的是小程序获取用户信息的,更新测试时间是2023-10-25 更改原因 首先,官网上的解释是这样的,为了安全合…...
Mysql 索引原理和优化方式
一、索引原理 什么是索引 索引是存储引擎用于快速找到记录的一种数据结构。可以联想到字典中的目录。 索引的分类 (1) Hash 索引 Hash 索引是比较常见的一种索引,他的单条记录查询的效率很高,时间复杂度为1。但是,…...
Ubuntu安装VM TOOLS解决虚拟机无法和WINDOWS粘贴复制问题
1:首先使用VMware Workstation安装一个Ubuntu的系统。 2:现在已经不建议安装VM TOOLS。建议安装OPEN-VM-TOOLS。 3:进入系统使用下面的命令安装。 sudo apt install open-vm-tools 4:提示下面错误,Package open-vm…...
【Docker】Docker Swarm介绍与环境搭建
为什么不建议在生产环境中使用Docker Compose 多机器如何管理?如何跨机器做scale横向扩展?容器失败退出时如何新建容器确保服务正常运行?如何确保零宕机时间?如何管理密码,Key等敏感数据? Docker Swarm介…...
国产CAN总线收发芯片DP1042 兼容替换TJA1042
说明 1 简述 DP1042是一款应用于 CAN 协议控制器和物理总线之间的接口芯片,可应用于卡车、公交、小汽车、工业控制等领域,支持 5Mbps CAN FD 灵活数据速率,具有在总线与 CAN 协议控制器之间进行差分信号传输的能力,完全兼容“ISO…...
[架构之路-243]:目标系统 - 纵向分层 - 架构是表面轮廓、内部骨架、未来蓝图,企业组织架构、信息系统架构、软件架构、应用程序就架构
目录 一、什么是架构 1.1 架构是表面轮廓 1.2 架构是内部骨架 1.3 架构是蓝图,是愿景 1.4 架构是数据流、控制流、管理流、同步流 1.5 数据、控制、同步、管理的比较 二、架构的层级 2.1 企业组织架构 2.2 企业系统架构 2.2 信息系统架构 2.3 软件架构 …...
【接口技术】定时计数器习题
1:8253芯片有______个端口地址。 【可选】 2 3 4 6 解答:4 2:8253芯片有______种工作方式。 【可选】 3 4 5 6 解答:6 3: 8253芯片内部有完全独立的______。 【可选】 6个16位计数通道 3个16位计数通道 6个8位计…...
DC电源模块的的散热结构合理布局
BOSHIDA DC电源模块的的散热结构合理布局 DC电源模块在工业控制、通讯、汽车电子等领域广泛应用。然而,随着功率密度不断提高,DC电源模块产生的热量也越来越大,散热问题变得越来越突出。为了保障电路的稳定性和可靠性,必须采取合…...
Fedora Linux 38下安装音频与视频的解码器和播放器
Fedora Linux 38 操作系统安装好后,默认是没有音频与视频的解码器的,音频与视频的播放体验非常差劲。但是第三方的软件源中有解码器和播放器的软件,需要我们自己手动安装。、 连接互联网,打开Shell命令行: 1. sudo d…...
边缘计算:云计算的延伸
云计算已经存在多年,并已被证明对大大小小的企业都有好处;然而,直到最近边缘计算才变得如此重要。它是指发生在网络边缘的一种数据处理,更接近数据的来源地。 这将有助于提高效率并减少延迟以及设备和云之间的数据传输成本。边缘…...
【经验分享】在Kylin桌面版操作系统中配置openGauss的ODBC数据源
引言 openGauss是一款开源的关系型数据库管理系统,它提供了强大的功能和性能,可以满足各种企业级应用的需求。与此同时,ODBC(Open Database Connectivity)是一个标准的数据库访问接口,它允许应用程序通过统…...
WSL——ubuntu中anaconda换源(conda、pip)
1、conda 打开Ubuntu,输入下列命令。 conda config --set show_channel_urls yes 在文件管理器地址栏,输入:\\wsl$。打开Ubuntu根路径,其中显示了.condarc文件。 以文本形式打开,并输入要换的源,保存即可。…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
