当前位置: 首页 > news >正文

【vue+nestjs】gitee第三方授权登录【超详细】

项目场景:

前端使用vue3+ts 后端使用nestjs


1.配置gitee第三方设置

1.找到账号设置
在这里插入图片描述
2.找到数据管理下的第三方应用
在这里插入图片描述
3.点击创建,进入配置
在这里插入图片描述
在这里插入图片描述

2.代码演示

特别注意:
如果你跟我一样是前后端分离的模式开发的,应用回调地址填写的应该是你的前端路由地址。在你的前端页面获取code,把code值传给后端接口。后端接口通过code获取gitee用户信息。

代码演示

我的应用回调地址:http://localhost:8080/vuecms/gitee

  1. 前端点击gitee图标登录代码:
<div @click="handleToLogin('gitee')">gitee
</div>const handleToLogin = (type:string)=>{window.location.href="http://localhost:3000/user/oauth/gitee"
}
  1. http://localhost:3000/user/oauth/gitee后端接口代码
	@Get('/oauth/gitee')async gitee(@Res() response: Response) {let cid = data.cid;let redirectUrl = data.redirectUrl;//回调路劲获取code//通过该路劲获取code,这里的回调地址就是你的前端地址response.redirect(`https://gitee.com/oauth/authorize?client_id=${cid}&redirect_uri=${redirectUrl}&response_type=code`)}
  1. 回调地址前端代码
<template><div class="u-f u-f-ac u-f-ajc" style="width: 100%;height:100vh"><template v-if="isOauth"><el-resulticon="success"title="授权成功,跳转中..."></el-result></template><template v-else><el-resulticon="error"title="授权失败"></el-result></template></div>
</template><script setup lang="ts">import {useRoute,useRouter} from "vue-router";import {onMounted} from "@vue/runtime-core";import {requestGiteeLogin} from "@/network/common/oauthPage";import {setToken, setUserId, setUsername} from "@/utils/storage";import {handleGetCurInstance} from "@/utils/utils";import {ref} from "vue"let route = useRoute()let router = useRouter()let query = route.query;let {model} = handleGetCurInstance()let isOauth = ref(true)onMounted(()=>{//获取返回的code,通过code对后端发起请求,获取gitee用户信息let {code} = query;let form = {code}requestGiteeLogin(form).then(res=>{let {data,code,message} = res;if(code==200){setToken(data.token)setUserId(data.id)setUsername(data.username)window.location.href="/"}else{model.handleMsg(message,"warning")isOauth.value =false;}})})
</script>
  1. requestGiteeLogin请求的后端代码
//gitee登录@Post('/oauth/giteeLogin')giteeLogin(@Body() giteeLoginDto:GiteeLoginDto,@IpAddress() clientIp: string) {let {code,operationSystem,browser} = giteeLoginDto//获取accessTokenlet accessToken = await this.handleGetGiteeAccessToken(code)if(!accessToken.data){return this.msgService.fail("code过期,请重新登录")}//使用accessToken获取gitee用户信息let giteeInfo:any = await this.getGiteeInfoByAccessToken(accessToken.data);if(!giteeInfo.data){return this.msgService.fail("获取gitee账号信息失败")}let { id, name, avatar_url, email } = giteeInfo.data;let giteeId = sysConfigEnum.giteeLoginConfig + JSON.parse(JSON.stringify(id));//判断gitee是否有关联账号。如果有就登陆,没有就新创建一个账号let userNum = await this.userEntity.createQueryBuilder().where({ giteeId:giteeId }).getCount()let username;//没有账号,注册帐号if(userNum<=0){let roleData = await this.roleEntity.createQueryBuilder().where({roleName:"试用角色"}).getOne()username = handleGetCode(8);username = await this.handleGetUsername(username);let originalPwd = handleGetCode(8);let password = JSON.parse(JSON.stringify(originalPwd))password = securityMd5(password)let userData;try {userData = await this.userEntity.createQueryBuilder().insert().values({username,originalPwd,password,giteeId:giteeId,roleId:roleData.id}).execute();}catch (error) {throw new HttpException(error,HttpStatus.SERVICE_UNAVAILABLE)}id = userData.identifiers[0]["id"]}else{let userData = await this.userEntity.createQueryBuilder().where({giteeId:giteeId}).getOne()username = userData.usernameid = userData.id;}let ip  = handleDealIpv6ToIpv4(clientIp)let token = this.authService.createToken({id,username,ip})await this.updateUserInfoStatus(id,token,ip,operationSystem,browser)return {id,username,token}}//随机生成账号async handleGetUsername (username){const num = await this.userEntity.createQueryBuilder().where({username}).getCount()if(num>0){username = handleGetCode(8);return this.handleGetUsername(username)}return username;}//获取gitee的accessTokenasync handleGetGiteeAccessToken(code:string):Promise<resInterface>{let key = sysConfigEnum.giteeLoginConfiglet data = await this.sysConfigService.handleGetSysData(key)if(!data.cid || !data.secret || !data.redirectUrl){return {data:false,msg:""};}let cid = data.cid;let redirectUrl = data.redirectUrl;//回调路劲获取codelet secret = data.secret;//回调路劲获取codelet authData = await axios.post(giteeOauthConfig.authURL,{code,client_id: cid,redirect_uri: redirectUrl,client_secret: secret,}).then(res=>{return res.data;}).catch(err=>{return err.data})if(authData?.error){return this.msgService.commonRes(false,authData?.error?.error_description);}else{return this.msgService.commonRes(authData?.access_token,"");}}//通过access_token获取gitee信息async getGiteeInfoByAccessToken(accessToken: boolean | string){let authData = await axios.get(giteeOauthConfig.giteeUserAPI+`?access_token=${accessToken}`).then(res=>{return res.data;}).catch(err=>{return err.data})if(authData?.error){return this.msgService.commonRes(false,authData?.error?.error_description);}else{return this.msgService.commonRes(authData,"");}}

3.特别注意

如果以上步骤都没问题。需要把本地测试回调地址改为线上路径

如果你还是不懂,你可以克隆下我的项目。开源免费。如果对你有帮助,给我一个star就行了
https://gitee.com/derekgo/vue-cms_xg

踩坑不易,还希望各位大佬支持一下 \textcolor{gray}{踩坑不易,还希望各位大佬支持一下} 踩坑不易,还希望各位大佬支持一下

📃 个人主页: \textcolor{green}{个人主页:} 个人主页: 沉默小管

📃 个人网站: \textcolor{green}{个人网站:} 个人网站: 沉默小管

📃 个人导航网站: \textcolor{green}{个人导航网站:} 个人导航网站: 沉默小管导航网

📃 我的开源项目: \textcolor{green}{我的开源项目:} 我的开源项目: vueCms.cn

🔥 技术交流 Q Q 群: 837051545 \textcolor{green}{技术交流QQ群:837051545} 技术交流QQ群:837051545

👍 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

如果有不懂可以留言,我看到了应该会回复
如有错误,请多多指教

相关文章:

【vue+nestjs】gitee第三方授权登录【超详细】

项目场景&#xff1a; 前端使用vue3ts 后端使用nestjs 1.配置gitee第三方设置 1.找到账号设置 2.找到数据管理下的第三方应用 3.点击创建&#xff0c;进入配置 2.代码演示 特别注意: 如果你跟我一样是前后端分离的模式开发的&#xff0c;应用回调地址填写的应该是你的前…...

node 第八天 使用前后端不分离的方式实现cookie登录验证

实现cookie登录, 第一次登录成功后, cookie由服务端设置并保存在客户端, 后续访问在cookie过期前 (过期时间由后端设置) 将不需要登录cookie出现的背景是 HTTP是无连接的&#xff0c;无状态的, 半双工(http2.0以下), 所以需要一个媒介存在http中, 服务端可以操作, 客户端也可以…...

Ubuntu系统如何进行网络连接-连接电脑局域网-物联网开发-Ubuntu系统维护

一、前言 在Ubuntu系统的维护中&#xff0c;我们常常需要对VMware中的Ubuntu虚拟机配置网络连接&#xff0c;以连接服务器下载或安装软件包以及进行网络通信等。 基于上述问题&#xff0c;本文将着重分享Ubuntu配置网络链接的若干方法。 二、网络连接模式 打开VM&#xff0c;右…...

STL库——Vector常见使用接口

一、介绍 1. vector是表示可变大小数组的序列容器&#xff0c;就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是可以动态改变的&#xff0…...

将文件(File 对象)分割成多个块

如果要将文件&#xff08;File 对象&#xff09;分割成多个块&#xff0c;可以使用 JavaScript 中的 Blob 和 File 构造函数以及数组的 slice 方法。以下是一个示例&#xff1a; // 创建一个 File 对象&#xff0c;例如从文件输入框获取的文件 const file document.getElemen…...

若要对多态类进行深拷贝,应使用虚函数的clone,而不是公开的拷贝构造赋值

拷贝一个多态类可能会导致切片问题&#xff0c;为了解决这个问题&#xff0c;应覆盖一个虚clone函数&#xff0c;让他根据实际类型进行复制并返回一个到新对象的所有权的指针&#xff08;std::unique_ptr&#xff09;,在派生类&#xff0c;通过使用所谓的协变返回类型来返回派生…...

同构字符串(C++解法)

题目 给定两个字符串 s 和 t &#xff0c;判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t &#xff0c;那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符&#xff0c;同时不改变字符的顺序。不同字符不能映射到同一个字符上&#xf…...

『Linux升级路』基本指令

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;Linux &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、认识操作系统 &#x1f4d2;1.1什么是操作系统 &#x1f4d2;1.2操作系统…...

python argparse解析参数

用法比较简单&#xff0c;直接看代码 import argparseargparser argparse.ArgumentParser(descriptionthis is a hello argparser program) argparser.add_argument(--arg1, -a, typestr, helparg1 has value) argparser.add_argument(--arg2, typestr, default"value2&q…...

【数据挖掘】数据挖掘、关联分析、分类预测、决策树、聚类、类神经网络与罗吉斯回归

目录 一、简介二、关于数据挖掘的经典故事和案例2.1 正在影响中国管理的10大技术2.2 从数字中能够得到什么&#xff1f;2.3 一个网络流传的笑话(转述)2.4 啤酒与尿布2.5 网上书店关联销售的案例2.6 数据挖掘在企业中的应用2.7 交叉销售 三、数据挖掘入门3.1 什么激发了数据挖掘…...

nodejs+vue 学生宿舍管理系统设计与实现

可将教师信息、宿管信息、学生信息、楼栋信息等输入到系统中。只有管理员才能录入相关的资料&#xff0c;按照提示&#xff0c;输入相应的资料&#xff0c;而“导入”则可以通过上传档案&#xff0c;导入成功后&#xff0c;相应的寝室就会相应的减少。在录入大楼的时候&#xf…...

汽车R155法规包含那些国家?

标签&#xff1a;R155法规国&#xff1b; R155强制标准&#xff1b;R155&#xff1b;UCNECE&#xff1b; R155是由联合国欧洲经济委员会&#xff08;UNECE&#xff09;的世界汽车行业论坛&#xff08;WP.29&#xff09;发布的法规&#xff0c;专门针对汽车的网络安全。因为它是…...

一个简易的低代码

前言 最近接手了一个低代码平台可视化大屏做二次开发&#xff0c;在这里做一些记录。 低代码平台简介&#xff1a;低代码平台是一种开发工具&#xff0c;它可以让开发人员使用简单的拖拽和配置来创建应用程序&#xff0c;而不需要编写大量的代码。低代码平台通常包括一个可视化…...

【JVM系列】- 类加载子系统与加载过程

类加载子系统与加载过程 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享学习心得&#xff0c;欢迎指正…...

Amazon图片下载器:利用Scrapy库完成图像下载任务

概述 本文介绍了如何使用Python的Scrapy库编写一个简单的爬虫程序&#xff0c;实现从Amazon网站下载商品图片的功能。Scrapy是一个强大的爬虫框架&#xff0c;提供了许多方便的特性&#xff0c;如选择器、管道、中间件、代理等。本文将重点介绍如何使用Scrapy的图片管道和代理…...

Unity中Shader的Pass的复用

文章目录 前言一、怎么实现Pass的复用1、给需要引用的Pass给定特定的名字2、在需要引用 Pass 的Shader中&#xff0c;在Pass的平行位置使用 UsePass "ShaderPath PassName" 二、实现一个没被遮挡的部分显示模型原本的样子&#xff0c;遮挡部分显示模型的XRay效果1、…...

vue内容自适应方法

Vue中可以通过以下几种方式实现内容自适应&#xff1a; 使用CSS媒体查询&#xff1a;使用CSS媒体查询可以根据屏幕大小来动态改变元素的样式。例如&#xff0c;可以设置一个div元素在屏幕宽度小于600px时宽度为100%&#xff0c;在屏幕宽度大于600px时宽度为50%。 使用Vue的计算…...

RustDay05------Exercise[41-50]

41.使用模块的函数 mod 是用于创建模块的关键字。模块是一种组织代码的方式&#xff0c;它可以包含函数 (fn)、结构体 (struct)、枚举 (enum)、常量 (const)、其他模块 (mod) 等。模块用于组织和封装代码&#xff0c;帮助将代码分割成可管理的单元。模块可以形成层次结构&…...

C语言实现通讯录(超详细)

1.实现怎样一个通讯录 实现一个通讯录联系人信息&#xff1a;1.可以保存100个人的信息名字2.添加联系人年龄3.删除指定联系人性别4.查找指定联系人电话5.修改指定联系人住址6.排序联系人7.显示所有联系人信息 2.通讯录的实现 2.1创建两个源文件和一个头文件 首先我们创建con…...

【Python机器学习】零基础掌握MinCovDet协方差估计

如何更精准地评估资产的风险和收益? 在投资领域,资产的风险和收益评估是至关重要的。传统的协方差矩阵虽然在某种程度上能反映资产间的关联性,但也存在一定的局限性。例如如果样本数量较少,传统的协方差矩阵可能会出现偏差,从而影响投资决策。 假设现在有一个投资组合,…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...