小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
本文同时参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
需求:
业务需要,当前H5应用需要嵌入钉钉中进行使用
基础配置
- 创建钉钉H5微应用(地址:钉钉开发平台->应用开发->企业内部开发->创建应用)
- 获取应用基础信息
- 权限开通
- 配置IP出口以及链接
- 查找登录相关API文档:
开发 (这里只给出主要封装代码)
- 创建项目 可以根据官方文档进行编写(django API: docs.djangoproject.com/zh-hans/2.0…
- 封装钉钉相关API
结构大致如图
服务端代码:
- 获取token
@retry(reraise=True, stop=(stop_after_delay(10) | stop_after_attempt(3)), wait=wait_random(min=1, max=3),
retry=retry_if_exception_type())
def get_token(self, *args, **kwargs) -> dict:
'''
:result 获取access_token
'''
path = 'gettoken'
params = {
"appkey": self.__appkey,
"appsecret": self.__appsecret
}
response = self.conn.get(
path=path,
params=params,
timeout=5
)
data = response.json()
errcode = data.get('errcode', -1)
if str(errcode) == "0":
result = data.get('access_token', {})
result = result if isinstance(result, str) else ""
return result
return {}
- 通过code获取人员信息
def getuserinfo(self, code: str, *args, **kwargs):
path = "/user/getuserinfo"
params = {
"access_token": self.get_token(),
"code": code
}
response = self.conn.get(
path=path,
params=params,
timeout=5
)
data = response.json()
errcode = data.get('errcode', -1)
if str(errcode) == '0':
result = data
result = result if isinstance(result, dict) else {}
user_id = result.get('userid')
response = self._get_user_detail(user_id)
return response
return {}
- 获取人员详情
def _get_user_detail(self, user_id: str, *args, **kwargs):
key = str(user_id) + "_get_user_detail"
info = redisClient.authcache('get', key)
if info:
return info
path = '/topapi/v2/user/get?access_token={}'.format(self.get_token())
params = {
"language": "zh_CN",
"userid": user_id
}
response = self.conn.post(
path=path,
params=params,
timeout=5
)
data = response.json()
errcode = data.get('errcode', -1)
if str(errcode) == '0':
result = data.get('result', {})
result = result if isinstance(result, dict) else {}
redisClient.authcache('set', key, result)
return result
return {}
前端代码
- PC端代码
<script src="https://g.alicdn.com/dingding/dingtalk-jsapi/2.10.3/dingtalk.open.js"></script>
<p>Opening with system default browser(Google Chrome Recommened) ... ...</p>
<script>
dd.ready(function () {
dd.runtime.permission.requestAuthCode({
corpId: "{{ corpId }}", // 企业id
onSuccess: function (result) {
dd.biz.util.openLink({
url: window.location.protocol + "//" + window.location.host + "{{ uri }}&code=" + result.code,//要打开链接的地址
onSuccess: function (result) {
/**/
},
onFail: function (err) {
}
});
},
onFail: function (error) {
alert(`钉钉认证失败! ${JSON.stringify(error)}`);
}
});
});
</script>
- mob端代码
<script src="https://g.alicdn.com/dingding/dingtalk-jsapi/2.10.3/dingtalk.open.js"></script>
<script>
dd.ready(function () {
dd.runtime.permission.requestAuthCode({
corpId: "{{ corpId }}", // 企业id
onSuccess: function (result) {
dd.biz.navigation.replace({
url: window.location.protocol + "//" + window.location.host + "{{ uri }}&code=" + result.code,//要打开链接的地址
onSuccess: function (result) {
/**/
},
onFail: function (err) {
}
});
},
onFail: function (error) {
alert(`钉钉认证失败! ${JSON.stringify(error)}`);
}
});
});
</script>
- 登录完成跳转访问主页(这里进行session的处理)
<script>
setTimeout(function () {
document.location.resession_dict
document.location.replace("{{ uri }}");
}, 0)
</script>
扫码登录页面实现
<p align="value" style="text-align:center">{{ title }}</p>
<div id="login_container" style="text-align:center"></div>
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
<script>
var url = encodeURIComponent('users/login/');
var goto = encodeURIComponent('https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid={{ appid }}&response_type=code&scope=snsapi_login&state=test&redirect_uri=' + window.location.protocol + "//" + window.location.host + url)
var obj = DDLogin({
id: "login_container",//这里需要你在自己的页面定义一个HTML标签并设置id,例如<div id="login_container"></div>或<span id="login_container"></span>
goto: goto,
style: "border:none;background-color:#FFFFFF;",
width: "300",
height: "400"
});
var hanndleMessage = function (event) {
var origin = event.origin;
console.log("origin", event.origin);
if (origin == "https://login.dingtalk.com") { //判断是否来自ddLogin扫码事件。
var loginTmpCode = event.data; //拿到loginTmpCode后就可以在这里构造跳转链接进行跳转了
console.log("loginTmpCode", loginTmpCode);
var url2 = "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid={{appid}}&response_type=code&scope=snsapi_login&state=NvSxTQh&redirect_uri=" + window.location.protocol + "//" + window.location.host + url + "&loginTmpCode=" + loginTmpCode;
console.log("url2", url2)
window.location.href = url2;
}
};
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('message', hanndleMessage, false);
} else if (typeof window.attachEvent != 'undefined') {
window.attachEvent('onmessage', hanndleMessage);
}
</script>