- 钉钉内嵌扫码登录
流程调用钉钉的sdk拿到code,通过code去请求后台拿登录凭证,凭证对接给第三方去调用token兑换用户信息,这边扫码只到拿code的流程,我这边对接了好几种登录方式appid从接口获取的,项目使用vue3+elementplus

效果图.png
这是官网给的最新内嵌二维码的登录方式
https://open.dingtalk.com/document/orgapp/tutorial-obtaining-user-personal-information
代码如下
//记得在index.html引入 <script src="https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js"></script>
<template>
<div class="login-by-dingtalk">
<div id="login_container"></div>
<div class="tips">
<el-tag type="warning">请使用钉钉扫码登录</el-tag>
</div>
</div>
</template>
<script setup>
const { proxy } = getCurrentInstance();
const appid = ref("");
const redirectUrl = ref(window.location.href.split("#")[0]); // 使用当前页面地址作为回调
// 获取钉钉配置
const getAppid = () => {
sa.ajax(
"xxxx/dingtalk_v2",
{},
(res) => {
appid.value = res.data.clientId;
initDingdingLogin();
},
{ type: "get" }
);
};
// 处理钉钉回调
const handleDingTalkCallback = (code) => {
//通过code拿后端ticket凭证
sa.ajax("/xxx/doLogin", { loginType: "dingtalk_v2", code }, function (res) {
});
};
// 初始化钉钉登录
const initDingdingLogin = () => {
window.DTFrameLogin(
{
id: 'login_container',
width: 260,
height: 260,
},
{
redirect_uri: encodeURIComponent(redirectUrl.value),
client_id: appid.value,
scope: 'openid',
response_type: 'code',
state: Date.now(),
prompt: 'consent',
},
(loginResult) => {
const {redirectUrl, authCode, state} = loginResult;
//可以链接跳转也可以在当前页面处理
handleDingTalkCallback(authCode)
},
(errorMsg) => {
// 这里一般需要展示登录失败的具体原因,可以使用toast等轻提示
console.error(`errorMsg of errorCbk: ${errorMsg}`);
},
);
};
onMounted(() => {
getAppid();
});
</script>
<style scoped lang="scss">
.login-by-dingtalk{
width: 100%;
display: flex;
flex-direction: column;
#login_container {
display: flex;
justify-content: center;
margin: 20px 0;
}
.tips{
display: flex;
justify-content: center;
}
}
</style>
- 钉钉免登
封装了一个js专门做钉钉的免登判断,return 一个promise
import * as dd from 'dingtalk-jsapi';
import { useSettingStore } from "../../store/setting";
import Cookies from 'js-cookie';
import { useStoreInfo } from "../../store/useStoreInfo";
export function ddCheckLogin() {
return new Promise((resolve, reject) => {
const settingStore = useSettingStore();
const storeInfo = useStoreInfo();
//检测是否有钉钉 的免登权限
if (settingStore.loginConfig?.granter.dingtalk_sso) {
//检测是否处于钉钉的环境
if (dd.env.platform === 'notInDingTalk') {
//不处于钉钉环境下直接跳过
resolve(true)
} else {
//处于钉钉环境
sa.ajax(
"xxx/dingtalk_sso",
{},
(res) => {
//接口获取id
dd.requestAuthCode({
corpId:res.data.dingTalkCorpId,
clientId:res.data.clientId,
onSuccess: function ({ code }) {
//拿到code调用后端获取登录凭证
sa.ajax("xxxx/doLogin", { loginType: "dingtalk_sso", code }, (ret)=> {
// 写入token
if (ret.data.token) {
Cookies.remove("ssp-center-satoken");
localStorage.setItem(
"ssp-center-satoken",
ret.data.token.tokenValue
);
} else {
return sa.alertError("服务器未返回 token 信息,无法登录");
}
//store存储token信息
storeInfo.setTokenInfo(ret.data.token);
// store存储用户信息
storeInfo.userInfo(ret.data.user);
});
},
onFail: function ({errorMessage}) {
resolve(true)
},
});
},
{ type: "get" }
);
}
} else {
resolve(true)
}
})
}
使用
onMounted(() => {
ddCheckLogin().then((res) => {
//不处于钉钉环境下处理的逻辑
if (res) {
}
});
});