前端使用vue3+ts 后端使用nestjs
1.找到账号设置
2.找到数据管理下的第三方应用
3.点击创建,进入配置
特别注意:
如果你跟我一样是前后端分离的模式开发的,应用回调地址填写的应该是你的前端路由地址。在你的前端页面获取code,把code值传给后端接口。后端接口通过code获取gitee用户信息。
代码演示
我的应用回调地址:http://localhost:8080/vuecms/gitee
<div @click="handleToLogin('gitee')">
gitee
</div>
const handleToLogin = (type:string)=>{
window.location.href="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`)
}
<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>
//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,"");
}
}
如果以上步骤都没问题。需要把本地测试回调地址改为线上路径
如果你还是不懂,你可以克隆下我的项目。开源免费。如果对你有帮助,给我一个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}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!
如果有不懂可以留言,我看到了应该会回复
如有错误,请多多指教