实现效果:
// dingtalkImg是钉钉图标的路径,网上找个放到项目里面就行
<img :src="dingtalkImg" alt="钉钉登录" class="DingTalk" @click="loginForDT">
const loginForDT = () => {
// getQrCodeApi 获取二维码的接口
getQrCodeApi().then(res => {
// 获取的二维码的路径
this.gotoUrl = res.data.data
// 显示二维码的弹出框
this.dialogDT = true
})
},
<!-- 显示二维码的弹出框 -->
<el-dialog v-model="dialogDT " title="钉钉授权登录" width="400px" :close-on-click-modal="false" @close="handleClose">
<div id="loginDT" style="transform: scale(.8); text-align: center;" />
</el-dialog>
window.DDLogin({
id: 'loginDT', // 显示二维码定义的id
goto: encodeURIComponent(this.gotoUrl),
style: 'border:none;background-color:#FFFFFF;',
width: '365',
height: '400'
})
二维码显示出来之后:
const DDMessage = (event) => {
const origin = event.origin
// 不用怀疑,写死的,都一样
if (origin === 'https://login.dingtalk.com') {
const loginTmpCode = event.data
const srcUrl = `https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${datas.appKey}&response_type=code&scope=snsapi_login&redirect_uri=${this.gotoUrl}&loginTmpCode=${loginTmpCode}`
window.open(srcUrl, '_self')
}
}
window.addEventListener('message', DDMessage, false)
onBeforeUnmount(() => {
window.removeEventListener('message', DDMessage, false)
})
为了提升用户体验,最好的方式是扫码登录之后不跳走,直接刷新当前页面自动登录,这一部分需要后端的配合,this.gotoUrl里面的重定向地址需要是系统的页面,只有跳转到系统里前端才能控制。
登录页监听路由变化
注意:钉钉扫码登录,它会在你给定的地址后面追加code和state两个变量,这两个是登录信息,而且只能访问一次,第二次访问这两个变量就会失效,钉钉开发者文档上有交代
watch: {
$route: {
handler: function(route) {
const query = route.query
if (query.code) {
// 如果路由里面有code这个变量,表示是通过钉钉扫码登录来的
this.getIsBand(query)
}
},
immediate: true
}
},
getIsBand(query) {
// 把钉钉追加的两个参数传给后端,判断是否已进行过绑定,
getBandApi(query).then(res => {
if (res) {
const data = res.data.data
// 如果没有绑定
if (!data.isBind) {
ElMessageBox({
title: '提示',
message: '<div style="line-height: 40px; text-align: center;">当前钉钉未绑定账号,请绑定后再进行登录</div><div style="line-height: 40px; text-align: center;">绑定步骤:登录系统-个人管理-基本信息</div>',
confirmButtonText: '确定',
dangerouslyUseHTMLString: true,
showCancelButton: false,
closeOnClickModal: false
}).then(() => {
// 如果没有绑定,我这里的设计是回到当前登录页,通过账号密码登入系统再进行绑定
this.$router.push({
path: '/login'
})
}).catch(() => {})
} else {
// 如果已经绑定过了,进行自己的登录逻辑
this.getToken(data)
}
}
})
},
小白一枚,如果有遗漏、错误或者不明白的欢迎联系,我们一起学习