SpringBoot + Vue实现Github第三方登录

news2024/10/5 22:40:35

        前言:毕业设计终于好了,希望能有空多写几篇

1. 获取Github账号的Client ID和Client secrets

        首先点击这个链接进入Github的OAuth Apps页面,页面展示如下:

之后我们可以创建一个新的apps:

        填写资料:

创建之后就可以获取到Client ID 和 Client Scrects

2. github用户信息获取流程

        获取到Client ID 和 Client Scrects之后,就可以开始写代码了,这里先放上接口文档

2.1 获取授权码Authorize Code

请求路径:

GET https://github.com/login/oauth/authorize

主要携带参数:

参数名称类型描述
client_idstring必需带上,注册时从GitHub收到的客户端ID。
redirect_uristring应用程序中的URL,授权后用户将被发送到该URL。
scopestring用空格分隔的作用域列表。如果未提供,则范围默认为未为应用程序授权任何范围的用户的空列表。对于已授权应用程序范围的用户,不会向用户显示包含范围列表的OAuth授权页面。
statestring一个随机字符串,用于防止跨站点请求伪造攻击。
allow_signupstring在OAuth流程中,是否会向未经身份验证的用户提供注册GitHub的选项。默认为true。当策略禁止注册时使用false。

请求的响应结果:

        前面参数中的redirect_uri填写的返回路径,同时这个返回路径会携带code和state,基于此,我们可以在前端定义一个跳转到 Github 授权页面的链接:

<a href="https://github.com/login/oauth/authorize?scope=user:email&client_id=请填写自己的client_id">Github登录</a>

(ps:这里我使用了个图标,一样的)

点击之后就有了这个画面:

        输入正确的密码之后,GitHub将重定向回站点,并在代码参数中携带code以及在前一步中提供的状态参数state。临时代码将在10分钟后失效。如果状态不匹配,则是第三方创建了请求,开发者应该中止该过程。

我们就可以使用Vue中的route获取这个code参数,

这里我的router.js中配置了返回路径对应路由:

const router = createRouter({

  history: createWebHistory(import.meta.env.BASE_URL),
  export default routes: [
    {
      path: "/",
      name: "post",
      component: Post,
    },
]});

然后在页面中拿到这个code 

onMounted(async() => {
    let code = route.query.code;
    if(code === undefined || code === null || code === ""){
        message.error("登录失败:code为空");
        return;
    }
   //然后发送这个code给后端就行了,很简单,不多赘述
});
2.2 通过授权码获取access_token

请求URL:

POST https://github.com/login/oauth/access_token

携带参数: 

参数名称类型描述
client_idstring必需!前面的获取Client ID
client_secretstring必需!前面获取的Client Secret
codestring必需!上一步获取到的code

返回参数:

Accept: application/json
{
  "access_token":"gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "scope":"repo,gist",
  "token_type":"bearer"
}

于是乎我们拿到了access_token

代码编写如下:

Map<String, Object> data = new HashMap<>();
        data.put("client_id", 你的client_id);
        data.put("client_secret", 你的client_secret);
        data.put("code", 收到的code);
        //        使用HttpUtil发送post请求
        String post = HttpRequest.post(accessTokenURL)
                .header(Header.ACCEPT, "application/json")
                .body(JSONUtil.toJsonStr(data))
                .execute().body();

然后再获取access-token:

String accessToken = null;
        try{
            JSONObject postResponse = JSONObject.parseObject(post);
            accessToken = postResponse.getString("access_token"); //获取密钥
            if(accessToken == null || accessToken.equals("")){
                throw new BusinessException(ErrorCode.LOGIN_ERROR);
            }
        }
        catch (Exception e){
            throw new BusinessException(ErrorCode.LOGIN_ERROR);
        }
2.3 根据access_token获取用户信息进行登录

请求地址:

Authorization: token ${access_token}
GET https://api.github.com/user

返回参数:

{
  "login": "STUkkkkkk",
  "id": 98441370,
  "node_id": "U_kgDOBd4Ymg",
  "avatar_url": "https://avatars.githubusercontent.com/u/98441370?v=4",
  "gravatar_id": "",
  "url": "https://api.github.com/users/STUkkkkkk",
  "html_url": "https://github.com/STUkkkkkk",
  "followers_url": "https://api.github.com/users/STUkkkkkk/followers",
  "following_url": "https://api.github.com/users/STUkkkkkk/following{/other_user}",
  "gists_url": "https://api.github.com/users/STUkkkkkk/gists{/gist_id}",
  "starred_url": "https://api.github.com/users/STUkkkkkk/starred{/owner}{/repo}",
  "subscriptions_url": "https://api.github.com/users/STUkkkkkk/subscriptions",
  "organizations_url": "https://api.github.com/users/STUkkkkkk/orgs",
  "repos_url": "https://api.github.com/users/STUkkkkkk/repos",
  "events_url": "https://api.github.com/users/STUkkkkkk/events{/privacy}",
  "received_events_url": "https://api.github.com/users/STUkkkkkk/received_events",
  "type": "User",
  "site_admin": false,
  "name": "小坤(Stukk)",
  "company": null,
  "blog": "",
  "location": null,
  "email": null,
  "hireable": null,
  "bio": "学习!",
  "twitter_username": null,
  "public_repos": 6,
  "public_gists": 0,
  "followers": 0,
  "following": 1,
  "created_at": "2022-01-26T03:23:04Z",
  "updated_at": "2024-03-02T11:57:33Z",
  "private_gists": 0,
  "total_private_repos": 2,
  "owned_private_repos": 2,
  "disk_usage": 33800,
  "collaborators": 0,
  "two_factor_authentication": false,
  "plan": {
    "name": "free",
    "space": 976562499,
    "collaborators": 0,
    "private_repos": 10000
  }
}

我们就可以封装这些数据进行登录啦!

代码:

//        获取github用户信息
        String userInfoURL = gitHubConstants.getUserInfoURL(); //获取用户登录信息的请求地址
        String userInfo = HttpRequest.get("https://api.github.com/user")
                .header(Header.AUTHORIZATION, "token " + accessToken)
                .header("X-GitHub-Api-Version", "2022-11-28")
                .execute().body();
        JSONObject userInfoJson = JSONObject.parseObject(userInfo);
        String githubId = userInfoJson.getString("id"); //这个是github的id
        LambdaQueryWrapper<User> userLambdaQueryWrapper =  new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getGithubId,githubId);
        User user = this.getOne(userLambdaQueryWrapper);
        if(user != null){
            // 3. 记录用户的登录态
            request.getSession().setAttribute(USER_LOGIN_STATE, user);
            return this.getLoginUserVO(user);
        }
//接下来看你的业务去写代码了
2.4 根据access_token获取用户邮箱

和上面一样,就是把user换成emails

Authorization: token ${access_token}
GET https://api.github.com/emails

响应结果:
 

[
    {
        "email": "xxx@qq.com",
        "primary": true,
        "verified": true,
        "visibility": "private"
    },
    {
        "email": "xxx@users.noreply.github.com",
        "primary": false,
        "verified": true,
        "visibility": null
    }
]

和前面的user一样,不赘述了。

3. 将Github用户信息与数据库进行比对,进行登录注册

        到此我们已经拿到了Github用户的信息,我们通过比对githubId来看看是否出现在数据库中,不在的话就进行注册,存在的话就登陆操作。

        比如我们可以数据库记录的是用户的id,githubId,用户名,邮箱等等如果用户第一次登录,插入一条记录,如果不是就进行数据库数据的比对进行登录,如果有错误,终止登录流程并进行提示。没有错误就把页面重定向到对应的前端页面,并且把用户信息返回给前端,这样就完成了第三方登录了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1630709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从关键新闻和最新技术看AI行业发展(2024.2.12-2.25第十七期) |【WeThinkIn老实人报】

写在前面 【WeThinkIn老实人报】旨在整理&挖掘AI行业的关键新闻和最新技术&#xff0c;同时Rocky会对这些关键信息进行解读&#xff0c;力求让读者们能从容跟随AI科技潮流。也欢迎大家提出宝贵的优化建议&#xff0c;一起交流学习&#x1f4aa; 欢迎大家关注Rocky的公众号&…

Redux入门:使用@reduxjs/toolkit构建React应用程序状态管理

随着应用程序复杂性的增加,有效管理应用程序状态变得越来越重要。Redux是一种流行的状态管理解决方案,随着应用程序复杂性的增加,有效管理应用程序状态变得越来越重要。Redux是一种流行的状态管理解决方案,但传统的Redux设置和使用过程比较繁琐。幸运的是,Redux官方团队推出了r…

【Linux】NFS网络文件系统搭建

一、服务端配置 #软件包安装 [roothadoop01 ~]# yum install rpcbind nfs-utils.x86_64 -y [roothadoop01 ~]# mkdir /share#配置文件修改 #格式为 共享资源路径 [主机地址] [选项] # [roothadoop01 ~]# vi /etc/exports /share 192.168.10.0/24(rw,sync,no_root_squash) #…

Git 使用 下载分支 提交新项目到当前分支 三(公司快速上手版)

文章背景 git已经装好了&#xff0c;公司的也给创建好账户了&#xff0c;仓库地址也有了。 领导已经给你说了是哪个分支了。 如何下载远程仓库中的一个项目分支&#xff0c;到本地电脑上。 并且如何将新建的项目上传到当前分支的远程仓库 下载 步骤 创建文件夹。 右键 Op…

springboot权限验证学习-上

创建maven项目 创建父工程 这类项目和原来项目的区别在于&#xff0c;打包方式是pom 由于pom项目一般都是用来做父项目的&#xff0c;所以该项目的src文件夹可以删除掉。 创建子工程 子工程pom.xml 父工程pom.xml 添加依赖 父工程导入依赖包 <!--导入springboot 父工程…

【MyBatis】初步解析MyBatis:实现数据库交互与关系映射的全面指南

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【MyBatis】初步解析MyBatis&#xff1a;实现数据库交互与关系映射的全面指南 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 前言什么是MyBatis?一. MyBa…

六.音视频编辑-创建视频过渡-概述

引言 目前我的应用已经实现了视频的编辑&#xff0c;音频的混合处理。随着时间的推进&#xff0c;两个不同场景的视频快速的切换&#xff0c;其中没有任何过渡效果。通常画面在时间轴上出现明显的变化时&#xff0c;两个场景间会使用一些动画的过渡效果。比如渐隐&#xff0c;…

麦肯锡报告:《在实现量子优势方面稳步推进》

2024年4月24日&#xff0c;麦肯锡一年一度的Quantum Technology Monitor发布了其最新的2024年研究报告&#xff0c;提供对全球量子技术&#xff08;QT&#xff09;、投资、生态系统等发展现状的见解。 此次&#xff0c;麦肯锡为第三届年度Quantum Technology Monitor报告所做的…

[C++]22:C++11_part_one

C11 一.列表初始化&#xff1a;1.{}初始化&#xff1a;2.C11扩大了列表初始化的范围&#xff1a;3.std::initializer_list1.简单类型的列表初始化&#xff1a;2.复杂类型的列表初始化3.实现vector的列表初始化4.实现list的列表初始化&#xff1a;5.不支持列表初始化&#xff1a…

多用户商城系统哪个好,2024多用户商城系统这样选

在2024年选择适合的多用户商城系统是一项至关重要的决策&#xff0c;因为一个优秀的商城系统不仅可以提升用户体验&#xff0c;还能够帮助企业实现业务目标并取得长期成功。然而&#xff0c;在众多的选择中挑选出最适合的一个并不容易&#xff0c;需要综合考虑各种因素&#xf…

网页模版如何用

现在的网页模版已经得到了许多人的喜爱和使用。随着人们对互联网的需求不断增加&#xff0c;更多的公司和组织需要拥有自己的网站&#xff0c;以推广他们的品牌和服务。而网页模版为他们提供了一个简单而高效的方法来创建自己的网站。 网页模版是预先设计好的网站模板&#xff…

docker容器通俗理解

前言 如果大家没使用过Docker,就在电脑上下载一个VMware Workstation Pro&#xff0c;创建一个虚拟机安装一个windows操作一下感受一下,为什么我的电脑上还以再安装一台windows主机&#xff1f;其实你可以理解为Docker就是Linux系统的一个虚拟机软件。 我的Windows也可以安装…

(学习日记)2024.05.08:UCOSIII第六十二节:常用的结构体(os.h文件)第一部分

之前的章节都是针对某个或某些知识点进行的专项讲解&#xff0c;重点在功能和代码解释。 回到最初开始学μC/OS-III系统时&#xff0c;当时就定下了一个目标&#xff0c;不仅要读懂&#xff0c;还要读透&#xff0c;改造成更适合中国宝宝体质的使用方式。在学完野火的教程后&a…

Java基础教程- 1 Java 简介

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 1 Java 简介 1.1 Java语言概述 1.1.1 Java是什么 &#xff08;了解一下即可&#xff0c;对学习没影响&#xff0c;总得了解一下它是怎么来滴~&#xff09; Java是由Sun公司&#xff08;已…

五一景点预约怎么预约 预约时间用备忘录设置提醒不怕错过

五一小长假即将来临&#xff0c;相信很多人和我一样&#xff0c;已经跃跃欲试&#xff0c;准备踏上旅途&#xff0c;去探索那些心仪已久的风景名胜。但在这个旅游高峰期&#xff0c;不少热门景点都需要提前预约购票。那么&#xff0c;怎么预约才能确保顺利游览呢&#xff1f; …

在智慧城市的建设中智能电表发挥什么作用

在智慧城市的建设中&#xff0c;智能电表扮演着至关重要的角色。智慧城市是一个利用信息技术手段提升城市运行效率和质量的新型城市模式&#xff0c;旨在通过信息和通信技术的应用&#xff0c;提高城市管理、公共服务、环境保护等方面的质量和效率&#xff0c;促进城市的可持续…

金价大跳水,美梦变噩梦!2024真正适合普通人的靠谱创业项目!2024适合30-40岁轻资产小生意

4月22日晚间&#xff0c;向上“狂飙”了一个多月的金价突然就“大跳水”。当日&#xff0c;每克金价均下调14块。在这次跳水中&#xff0c;有人欢喜有人愁&#xff1a;有投资者自报做空金价一夜狂赚14万&#xff0c;也有投资者哭诉&#xff0c;头晚进货到早上就净亏损2万&#…

中电金信:GienTech动态| 获奖、合作、与伙伴共谋数字化转型…

—— —— GienTech动态 —— —— 中电金信携“源启”亮相第十二届中国电子信息博览会 4月11日&#xff0c;为期三天的“第十二届中国电子信息博览会”在深圳顺利闭幕。中国电子信息博览会是中国规模最大、最具国际影响力的电子信息产业盛会之一。本届大会以“全球视野&#x…

AI预测福彩3D第9套算法实战化测试第6弹2024年4月28日第6次测试

今天继续进行新算法的测试&#xff0c;今天是第6次测试。好了&#xff0c;废话不多说了&#xff0c;直接上图上结果。 2024年4月28日福彩3D预测结果 6码定位方案如下&#xff1a; 百位&#xff1a;5、4、9、3、1、0 十位&#xff1a;2、3、5、6、1、7 个位&#xff1a;4、5、0、…

Goby 漏洞发布|禅道 /api.php/v1/users 未授权访问漏洞

漏洞名称&#xff1a;禅道 /api.php/v1/users 未授权访问漏洞 English Name&#xff1a;Zen Road /api.php/v1/users Unauthorized Access Vulnerability CVSS core: 9.8 影响资产数&#xff1a;69265 漏洞描述&#xff1a; 禅道是一款开源的项目管理软件&#xff0c;旨在…