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

news2025/3/11 3:16:16

项目场景:

前端使用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-result
                    icon="success"
                    title="授权成功,跳转中..."
            >
            </el-result>
        </template>
        <template v-else>
            <el-result
                    icon="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
     //获取accessToken
    let 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.username
      id = 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的accessToken
  async handleGetGiteeAccessToken(code:string):Promise<resInterface>{
    let key = sysConfigEnum.giteeLoginConfig
    let 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;//回调路劲获取code
    let secret = data.secret;//回调路劲获取code
    let 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}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

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

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

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

相关文章

MATLAB——神经网络参考代码

欢迎关注“电击小子程高兴的MATLAB小屋” %% I. 清空环境变量 clear all clc %% II. 训练集/测试集产生 %% % 1. 导入数据 load spectra_data.mat %% % 2. 随机产生训练集和测试集 temp randperm(size(NIR,1)); %打乱60个样本排序 % 训练集——50个样本 P_train NIR(…

Bootstrap Collapse的使用

1、效果图&#xff1a; 2、当点击B或C时&#xff0c;A自动收缩&#xff1a; 3、html代码&#xff1a; <div class"panel-group" id"accordion" role"tablist" aria-multiselectable"true"><div class"panel panel-de…

促进国内凝聚态物理理论与统计物理及交叉学科的学术交流及促进学科发展,与龙讯旷腾相约济南

全国凝聚态理论与统计物理学术会议旨在促进国内凝聚态物理理论与统计物理及交叉学科的学术交流及促进学科发展。自创办以来已成功举办20届&#xff0c;对提升我国物理学科的水平发挥了重要作用。第二十一届全国凝聚态理论与统计物理学术会议将于2023年10月20日-22日在济南召开&…

微信批量发朋友圈,多个号同步

近年来&#xff0c;随着数字营销的飞速发展&#xff0c;越来越多的企业开始将客户引至微信&#xff0c;并通过群发广告和发布朋友圈等方式进行产品推广&#xff0c;以实现高效率、低成本和良好的转化效果。随着号多起来了&#xff0c;朋友圈推广工作变得愈发繁琐&#xff0c;需…

手机拍照转机器人末端坐标(九点标定法)

1.打印标定纸&#xff0c;随机九个点 2.让UR机器人末端分别走到P1-P9九个点 在图示位置读取九个点的X&#xff0c;Y坐标 3.手机拍照&#xff08;固定点&#xff09; 测试可以随机拍一张&#xff0c;实用的话需要固定手机的拍照位置&#xff0c;得到的图片如下&#xff1a; 4.…

21.1 stm32使用LTDC驱动LCD--配置说明

本文讲解如何配置LTDC驱动LCD的参数配置&#xff0c;以及CubeMx参数配置说明 本文使用的是淘宝买的一块带电容触摸的液晶显示屏&#xff1a;5寸TFT液晶显示屏高清800*480免驱40P通用RGBIPS全视角彩屏GT911 说实话&#xff0c;价格还是相对挺便宜的&#xff0c;值得入手&#xf…

爱胜品YPS-1133DN系列打印机与奔图P3301DN打印机耗材更换的简单对比说明

速印机&#xff08;理想、荣大等&#xff09;、复印机&#xff08;夏普、理光、佳能、震旦等全系列&#xff09;、打印机、扫描仪、传真机、多媒体教学一体机、交互式电子白板、报警器材、监控、监考设备、特种安防设备维护及维修。吴中函 某用户的爱胜品YPS-1133DN Pro、爱胜品…

多货币一件铺货跨境电商商城开发

无论你身处世界的哪个角落&#xff0c;都能够畅享全球购物的便利。多货币一件铺货跨境电商商城是为了满足每个消费者的购物需求而精心打造的。无论你喜欢的是日本的时尚潮品、韩国的美妆产品&#xff0c;还是欧美的奢侈品和家居用品&#xff0c;我们都可以为你提供一站式购物服…

通讯录的实现(增删查改排序)

本课题模拟通讯录的实现&#xff0c;包括&#xff1a; 1.增加联系人的信息 2.删除联系人 3.查找联系人 4.修改联系人信息 5.对联系人进行排序 本节目录&#xff1a; 通讯录的实现样貌展示&#xff1a;这就算通讯录的菜单 下面对每个功能进行模块性讲解。 一、通讯录变量…

领英如何注册?2023超全面详细教程

领英是一家面向商业用户的全球最大的职业社交网站&#xff0c;据统计&#xff0c;Linkedln用户每月与网页的交互次数超过10亿次。对于跨境人来说&#xff0c;他更是作为一个开发客户、广告营销的工具&#xff0c;被称为跨境的“风口”。 一、领英被封原因 1、IP、设备问题 1&…

QT中使用QVTKOpenGLNativeWidget的简单教程以及案例,利用PCLVisualizer显示点云

先添加一个带有ui的QT应用程序。 一、在ui界面中添加QVTKOpenGLNativeWidget控件 先拖出来一个QOpenGLWidget控件 修改布局如下&#xff1a; 然后将QOpenGLWidget控件提升为QVTKOpenGLNativeWidget控件&#xff0c;步骤如下&#xff1a; 右击QOpenGLWidget窗口&#xff0c;选…

Linux系统下的shell外壳

往期回顾: ⭐Linux系统常用指令(一) ⭐Linux系统常用指令(二) ⭐Linux系统常用指令(三) ⭐Linux系统常用指令(完) 本篇文章我们来深挖Linux的知识! Linux严格意义上说的是一个操作系统&#xff0c;我们称之为“核心&#xff08;kernel&#xff09; “ &#xff0c;但我们一般用…

技术路线决定出海方向:中国车企的全球市场密码

摘要&#xff1a;面对全球化的挑战,中国汽车企业站在了一个十字路口:选择大众市场还是豪华市场?背后涉及的不仅是消费者的购车偏好,更有技术路线和产业链的深层次支撑。从丰田的Prius到宝马的驾驶乐趣&#xff0c;不同的市场策略背后隐藏着怎样的全球化密码? 随着全球化浪潮的…

网络库OKHTTP(3)拦截器扩展,一个好用的网络请求监控工具Chuck

序、慢慢来才是最快的方法。 场景一 明明是服务端的接口数据错误&#xff0c;而QA&#xff08;测试&#xff09;第一个找到的可能是客户端开发的你&#xff0c;为什么这个页面出现错误了&#xff1f; 而作为客户端开发的你&#xff0c;可能要拿出测试机连上电脑&#xff0c;打…

ftp服务开启——windows

一、打开服务 1、打开控制面板——》选中程序和功能 2、 选择启用或关闭windows功能 3、全选FTP服务器&#xff0c;web管理工具里面的IIS管理控制台&#xff0c;一个都不能漏 4、全选 万维网服务下面的安全性的所有选项&#xff0c;最后点击确定 二、 IIS 配置 1、windows的…

如何使用ai去水印?用这款就够了

AI在图像处理领域的不断成熟确实为我们提供了更多便利和高效率的工具&#xff0c;使得图像处理变得更加便捷&#xff0c;尤其是AI去水印技术&#xff0c;它可以轻松去除图片中的各种杂质&#xff0c;包括水印、文字、标志、物体、以及其他杂乱的干扰元素&#xff0c;有效提高了…

SSM - Springboot - MyBatis-Plus 全栈体系(三十一)

第七章 MyBatis-Plus 二、MyBatis-Plus 核心功能 1. 基于 Mapper 接口 CRUD 通用 CRUD 封装 BaseMapper (opens new window)接口&#xff0c; Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器! 内部包含常见的单表操作&#xff01; 1.1 Insert 方…

LoongArch 指令集设计——单周期5条指令exp5

对应实验手册请参阅《LoongArch CPU设计实验》。 NOTE: minicpu_env/miniCPU/目录下的代码功能不全&#xff0c;是有意为之&#xff0c;无需提issue修正。mycpu_env/myCPU/目录下的代码有功能错误&#xff0c;亦是有意为之&#xff0c;无需提issue修正。 实验安排简介 // dc…

E053-web安全应用-Brute force暴力破解初级

课程分类&#xff1a; web安全应用 实验等级: 中级 任务场景: 【任务场景】 小王接到磐石公司的邀请&#xff0c;对该公司旗下的网站进行安全检测&#xff0c;经过一番检查发现该论坛的后台登录页面上可能存在万能密码漏洞&#xff0c;导致不知道账号密码也能登录后台&am…

Windows消息 队列

1、 Windows消息机制 Windows是一个消息驱动的操作系统&#xff0c;消息是用一个常量标识符来标记&#xff0c;并且有两个32Bit的消息附加信息。单击鼠标、敲击键盘&#xff0c;都会通过电脑外设向系统发送特定的中断信号&#xff0c;这个中断信息在操作系统中会转化为一个消息…