一、登录钉钉开发者平台配置app_id,redirect_uri
登录钉钉开发者平台,需要配置两个东西
1.app_id
2.redirect_uri,这里的redirect_uri即为后台管理的登录地址,例如:http://www.test.com/login
二、封装钉钉登录组件(重点)
1.DDLogin.vue组件
html代码如下:
<template>
<div class="flex-center dd-login">
<a-spin
v-if="scanned"
class="flex-center"
style="height: 300px"
tip="登录中..."
>
</a-spin>
<iframe
v-else
:src="DDLoginUrl"
width="365px"
height="292px"
frameborder="0"
allowtransparency="true"
scrolling="no"
></iframe>
</div>
</template>
js代码如下(这边用的是vue3语法,用vue2语法的小伙伴可以自行转化代码,原理一样):
<script setup>
import { onMounted, ref } from "vue"; // vue3 按需引入
import AntD, { message } from "ant-design-vue/es"; // 这边用到的antUI框架
import { useRoute, useRouter } from "vue-router"; // 路由
import LoginRequest from "../http/modelApi/Login/index"; // 登录的http请求
import { setStorageItem } from "@/utils/StorageManager"; // 本地存储sessionStorage
const props = defineProps({
redirectPath: { // 钉钉后台配置的redirect_uri
type: String,
default: "",
},
appId: { // 钉钉后台配置的app_id
type: String,
default: "",
},
});
const scanned = ref(false); // 登录加载的loading
const DDLoginUrl = ref(""); // 用来加载钉钉的二维码
/**
* @function addListener
* @description 添加事件监听
*/
function addListener() {
window.addEventListener("message", handleReceiveTempCode, false);
}
/**
* @function removeListener
* @description 移除事件监听 登录成功之后 跳转之前应主动调用一次
*/
function removeListener() {
window.removeEventListener("message", handleReceiveTempCode);
}
/**
* @function getQRCode
* @description 获取登录二维码
*/
function getQRCode() {
// encodeURIComponent进行转码,解决浏览器对特殊参数强制转码导致的url错乱的问题。
const t = new Date().getTime();
const redirect_uri = encodeURIComponent(
window.location.origin + props.redirectPath
);
const goto = encodeURIComponent("https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=" +props.appId+"&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" + redirect_uri);
// 二维码展示地址
DDLoginUrl.value = `https://login.dingtalk.com/login/qrcode.htm?goto=${goto}&t=${t}`;
}
/**
* @function handleReceiveTempCode
* @description 获取临时登录code
*/
function handleReceiveTempCode(resp) {
const { origin, data: code } = resp;
//判断是否来自ddLogin扫码事件。
if (origin === "https://login.dingtalk.com") {
removeListener();
const redirect_uri = encodeURIComponent(
window.location.origin + props.redirectPath
);
window.location.href =
"https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=" +
props.appId +
"&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" +
redirect_uri +
"&loginTmpCode=" +
code;
}
}
function getAdminInfo(code) {
const router = useRouter();
LoginRequest.postLogin({
authType: "DINGTALK",
dingTalkCode: code,
})
.then((res) => {
message.success("登录成功");
setStorageItem(
"token",
res.token_type + " " + res.access_token,
"session"
);
setTimeout(() => {
router.replace("/index"); // 登录成功跳转到后台首页
}, 1500);
})
.catch(() => {
message.error("登录错误");
});
}
onMounted(() => {
const route = useRoute();
const router = useRouter();
const { code } = route.query;
if (code) {
scanned.value = true;
router.replace(props.redirectPath);
getAdminInfo(code);
} else {
addListener();
getQRCode();
}
});
</script>
三、登录页面调用封装的组件
1.login.vue页面中调用
html代码如下:
<template>
<d-d-login
:app-id="ddAppKey"
redirect-path="/login"
/>
</template>
js代码
<script>
import DDLogin from '@/components/DDLogin.vue'
import { useRouter,useRoute } from 'vue-router'
import { ref, reactive, toRefs, getCurrentInstance } from 'vue'
export default {
components: {
DDLogin,
},
setup() {
const router = useRouter()
const route = useRoute();
const { code } = route.query;
const ddAppKey = ref('app_id') // 这里就是正式和测试的app_id 可以通过env配置环境变量的形式来获取
if (code) {
router.replace("/login");
}
return {
tabIndex,
ddAppKey,
}
},
}
</script>