今天我们记录一下关于vue进行web开发的过程中对接钉钉的H5微应用的时候扫码登录的功能,你说他难吧,其实不难,很简单,你说他简单吧,看文档可能真的有点乱,不然您也不会来看我的帖子,我也看了别的大佬们写的关于这个的记录,不是说写的有问题,只是说很少有人站在别人开发的角度看待问题,导致很多人觉得还是不明白,所以今天就我写的过程中出现的问题进行描述一下大家可能迷茫的地方,尽量让每个开发者都看得懂! 感谢以下提供支持的博主: 填了个大空 易-水寒
https://oapi.dingtalk.com/connect/qrconnect?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI
这个需要你们的管理员进去,然后按照图示找到配置的地方,这里有人就问了,这个地址写什么?一般的话写的是您的web的登录入口的地址,比如说我的是https://csdn.clearlove/#login,那么你们就写自己的登录地址就好了。
有了以上两个参数,就基本ok了,很多博主也是写到这里就不写了,所以很多人就迷茫了,这也不行啊,怎么登录的啊,下面的步骤是登录的部分,如果您使用了方案一,会发现点击扫码登录的时候会直接跳到一个新的页面,然后生成一个二维码,就像这样:
有人说这个二维码怎么跳转过来的,很简单,就一个href,写一个span或者按钮的东西,事件绑定到下面的这个函数,点击执行函数就可以了,代码如下:
//扫码登录
sweep_code() {
window.location.href = "https://oapi.dingtalk.com/connect/qrconnect?appid=*******************&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=https://csdn.clearlove/#/login"
}
-我们使用下面的代码进行获取url中的code 和state
/**
* @aim get code from url
* @author clearlove
* @data 19-09
*/
export default {
getUrlKey:function(name){
return decodeURIComponent((new RegExp('[?|&]'+name+'='+'([^&;]+?)(&|#|;|$)').exec(location.href)||[,""])[1].replace(/\+/g,'%20'))||null;
}
}
this.code = this.$utils.getUrlKey('code') //这个是用来给后端获取用户信息的
this.state = this.$utils.getUrlKey('state') //这个只是为了防止攻击的, 没有这个参数也可以,看后端要不要这个参数了,具体情况来定
以上是第一种方案,我这么写估计都明白了,还不明白的话,就下面留言吧!
很多人迷茫的更多的是使用方案2进行实现的过程,那其实方案2和方案一的区别就是一个体验稍微好点,因为不用跳转页面了,就比如我做的这个:
这种的实现过程其实差不多的,下面分两种情况,第一种是使用vue2.0版本的,第二种是vue3.0版本的
直接在您的index.html中引入如下的代码
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
然后在登录的页面进行二维码的生成,这里说一点,就是二维码的生成以后的操作和方案一是一摸一样的,所以方案二我写的时候就写到如何生成二维码,有了二维码以后 ,扫码、回调、获取code、根据code获取用户信息、登录这一系列就和方案一一模一样了,这也是为什么方案一写的那么详细的原因,废话不多话,引入上面的钉钉的js以后呢,接着在页面上找一块你需要生成二维码的div,比如这样:
<div style="height: 310px;background: #ffffff" id="ding-login" v-show="isShow === 'ding'"></div>
dingLogin() {
this.$nextTick(() => {
var obj = DDLogin({
id: "ding-login",
goto: this.http_url,
style: "border:none;background-color:#FFFFFF;",
width: "300", // 二维码的宽度
height: "300" // 二维码的高度
})
// 重置扫码登录框的样式,让登录框居中
let box = document.getElementById('ding-login')
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'
})
},
说明:dingLogin这个函数就是点击扫码登录的时候调用的函数
scansettings().then(res => {
this.appid = res.data.appkey
this.appSecret = res.data.appsecret
this.redirect_uri = res.data.redirect_uri
this.redirects = encodeURIComponent(this.redirect_uri)
this.http_url = encodeURIComponent("https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=" + this.appid + "&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" + this.redirects + "")
// 获取到扫码结果,并且跳转获取临时登录码
var handleMessage = function (event) {
var origin = event.origin;
if (origin == "https://login.dingtalk.com") {
var loginTmpCode = event.data;
let url = "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=" + this.appid + "&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" + this.http_url + "&loginTmpCode=" + loginTmpCode + ""
location.href = url
} else {
console.info(event)
}
};
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('message', handleMessage, false);
} else if (typeof window.attachEvent != 'undefined') {
window.attachEvent('onmessage', handleMessage);
}
}).catch(err => {
console.error(err)
})
这里很多人看完以后就迷茫了,我简单的解释一下,官方给的源代码是这样的,官方源代码,区别在哪呢?其实就是参数获取的问题,因为这里我的appid和appSecret和回调的地址redirect_uri都是后端接口((scansettings)返回的,所以我页面加载的时候就直接请求接口,进行参数的获取,这里如果您这三个参数都是您自己写死的,那么您完全可以直接使用官方的代码,不过要加一行,也就是 kk = url这点代码,不然没办法回调回来,官方说的原话是“获取到loginTmpCode后就可以在这里构造跳转链接进行跳转了”,具体怎么跳转,就是这点代码,然后你会发现二维码扫码以后就可以直接回调了,然后和方案一就一样了,这里还有一个点需要注意,就是回调的地址需要encodeURIComponent进行转码,这步是为了解决浏览器对特殊参数强制转码导致的url错乱的问题。
components: {
'dingtalk': {
render(createElement) {
return createElement(
'script',
{
attrs: {
type: 'text/javascript',
src: 'https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js',
},
},
);
},
},
},
<dingtalk></dingtalk>
这样就引入了 ,下面的写法就和2.0一样了!
这个就比较简单了,上面的函数一样的写,区别在于vue存在生命周期,所以我们可以在created中实现code的获取,那一般的web项目我们只需要写到windows.onload的时候就可以了,有人就觉得,那么如果是两种方式(账号登录和扫码登录)都支持的话,是不是每次进来的时候就会报错呢?提示什么code不存在什么的,这个问题很好解决,只要我们获取code之前if判断一下code是不是存在,不存在再进行code的获取就好了!
如果对这个扫码登录还有什么问题的话,可以留言,我看到的会及时回复的,我追求的是博客不写就不写了,既然写了,就追求每个开发者都看得懂!