无理的新需求。。公司自己内部系统,接入钉钉扫码登录。。。
https://ding-doc.dingtalk.com/doc#/serverapi2/etaarr
钉钉开发文档
注意,上面这一步得联系管理员去操作,因为只有管理员可以登录钉钉开发者平台
这里使用方式有 两种
第一种是跳转连接到一个页面,扫码登录之后返回
第二种是直接在页面上显示扫码
这里我用的第二种方式,代码如下
首先引入需要的js,这里我选择在html引入
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>后台管理系统</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
<meta name="keywords" content="" />
<meta name="description" content="" />
</head>
<body>
<div id="app"></div>
</body>
// 将文档中需要引入的js引入到页面
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
</html>
然后在登录页写一个div,用来做包裹二维码的容器
<!------------- 钉钉扫码登录 ------------->
<template>
<div id="ding-login" v-if="isShow == 'ding'"></div>
<button @click="dingLogin">点击显示二维码</button>
</template>
<script>
import qs from 'qs'
// 钉钉后台获取的appid和appSecret,appSecret没有用到扫码中
let appid= '**************************'
let appSecret = '**************************'
// 重定向地址,因为vue用的hash,所以网址后面是 #/
let redirect = encodeURIComponent(`http://www.******.com/#/`)
// 官网给的跳转连接格式
let http_url = encodeURIComponent(`https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${appid}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${redirect}`)
export default {
data () {
return {
isShow: '', // 控制扫码窗口显示
code: qs.parse(window.location.hash.substring(3)).code // 获取的临时登陆码
}
},
created() {
// 如果临时登录吗存在,执行登录方法
if(this.code){
/* 这里写登录方法 */
return false
}
// 获取到扫码结果,并且跳转获取临时登录码
var handleMessage = function (event) {
var origin = event.origin;
if (origin == "https://login.dingtalk.com") { //判断是否来自ddLogin扫码事件。
// 拿到 loginTmpCode 后,跳转连接拿到临时登陆码,之后返回到跳转的地址,会携带临时登陆码
var loginTmpCode = event.data;
let url = `https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${appid}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${http_url}&loginTmpCode=${loginTmpCode}`
// 这边直接打开拼接好的连接,去获取临时登录码,回来地址在下面
location.href = url
}
};
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('message', handleMessage, false);
} else if (typeof window.attachEvent != 'undefined') {
window.attachEvent('onmessage', handleMessage);
}
},
methods () {
// 切换钉钉登录
dingLogin () {
this.isShow = 'ding'
// 这边需要用 $nextTick() 方法来等DOM渲染完成后,才能获取到盒子容器($nextTick 方法见另一篇文章)
this.$nextTick(() => {
// 钉钉登录,参数文档中那些其他项就不展示了,按照文档自己配置就可以
var obj = DDLogin({
id: "ding-login",
goto: http_url,
style: "border:none;background-color:#FFFFFF;",
})
// 重置扫码登录框的样式,让登录框居中
let box = document.getElementById('ding-login')
box.querySelector('iframe').style.position = 'absolute'
box.querySelector('iframe').style.top = '0'
box.querySelector('iframe').style.bottom = '0'
box.querySelector('iframe').style.left = '0'
box.querySelector('iframe').style.right = '0'
box.querySelector('iframe').style.margin = 'auto'
})
}
}
}
</script>
页面效果如图
获取回来code地址格式如下,这也是为什么会用qs去格式化截取前三位后的hash值
http://www.**********.com/#/?code=****************************&state=STATE
code 就是临时登录码,拿到后传给后台,来获取登录状态
详细解释如下
因为钉钉提供的js文件内容是通过 document.getElementById 来获取盒子容器的
而且在盒子中 innerHTML 出一个 iframe 标签来引入一个网页,这个引入的就是二维码图片,所以,在 nextTick 方法中会改变 box 里面 iframe 标签的属性让他居中。
这样页面中就显示了钉钉扫码登录的二维码了,扫码后返回的结果用文档中提供的方法
来获取到临时登录码,传给后台获取登录验证,因为涉及公司内部信息就不展示了,相信只要页面上二维码能显示出来,其他的就好做了
谢谢