钉钉SDK

对接sdk还是遇到不少问题的

文章目录

  • 钉钉SDK
    • 一. 第三方web网站扫码登录
      • 1. 流程
    • 二. 加解密
      • 1.注册事件
    • 三. 调试

钉钉python版SDK文档地址: https://dingtalk-sdk.readthedocs.io/zh_CN/latest/
钉钉官方服务端文档: https://open-doc.dingtalk.com/microapp/serverapi2

为了避免调试出现不必要的参数错误,前期钉钉配置要做好,血和泪的教训?

准备好下面几个参数

DINGTALK_CORP_ID = "重点:企业应用ID"
# 钉钉微应用
DINGTALK_APP_KEY = "微应用APP_KEY"
DINGTALK_CORP_SECRET = "微应用SERCRET"
# 钉钉移动应用(扫码登录),在移动应用接入菜单里配置
DINGTALK_APP_ID = "移动应用APP_ID"
DINGTALK_APP_SECRET = "移动应用APP_SECRET"
# 钉钉aes加密(随机)
DINGTALK_AES_TOKEN = "43位字符串 a-zA-Z0-9中生成"
DINGTALK_TOKEN = "字符串随便填"

一. 第三方web网站扫码登录

1. 流程

钉钉扫码—>判断是否公司员工—>登录

关于web系统的两种接入方式,都只能获取到用户的钉钉身份,并不能获取到用户是否在企业中

解决方法:

批量同步钉钉人员信息到数据库,登录后匹配数据库,新进员工通过钉钉回调同步到数据库,回调未生效人工审核后手动更新数据库

由于钉钉开发文档读的不够仔细导致调试频繁出错,所以开发流程我简单说,把细节放大

  1. 前端导入钉钉scrpit文件开发扫码页面

    <script src="//g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
    <script>
    var url="http://erp.vaiwan.com/api/v1.0/ding_test";
    var goto = encodeURIComponent('https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingoadwjj1iszubeh9rnf&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+url);
    var obj = DDLogin({id:"login_container",goto: goto,style: "border:none;background-color:#FFFFFF;",width : "365",height: "400"});var hanndleMessage = function (event) {var origin = event.origin;console.log("origin", event.origin);//判断是否来自ddLogin扫码事件。if( origin == "https://login.dingtalk.com" ) {//拿到loginTmpCode后就可以在这里构造跳转链接进行跳转了var loginTmpCode = event.data;console.log("loginTmpCode", loginTmpCode);if(loginTmpCode){let uri="https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingoadwjj1iszubeh9rnf&response_type=code&scope=snsapi_login&state=STATE&redirect_uri="+url+"&loginTmpCode="+loginTmpCode;// 跳转location.href = uri;}}
    };if (typeof window.addEventListener != 'undefined') {window.addEventListener('message', hanndleMessage, false);
    } else if (typeof window.attachEvent != 'undefined') {window.attachEvent('onmessage', hanndleMessage);
    }
    </script>
    
  2. 配置扫码后跳转页面(就是第一步goto参数里的url),钉钉会自动在跳转页面路由后添加codestate参数

  1. 拿到code请求后端接口

    <script src="https://cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
    <script>// location.search: "?code=bb42ec66ed5...&state=STATE"let code = location.search.split("&")[0].split("=")[1];$.ajax({type:"post",url:'http://erp.vaiwan.com.cn/api/v1.0/getinfo',data:{"code":code},success:function(data){console.log(data)}})
    </script>
    
  2. 后端用appid和appsecret获取access_token

    import requests
    from dingtalk.client import SecretClientclass GetInfoByCode(object):def __init__(self):self.url = "https://oapi.dingtalk.com/sns"def get_access_token(self):resp = requests.get(url=self.url + "/gettoken",params=dict(appid=DINGTALK_APP_ID, appsecret=DINGTALK_APP_SECRET))resp = resp.json()return resp["access_token"]
    
  3. 用access_token和code获取用户unionid

    def get_persistent_code(self, code, token):resp = requests.post(url="%s/get_persistent_code?access_token=%s" % (self.url, token),json=dict(tmp_auth_code=code),)resp = resp.json()return resp["unionid"]
    
  4. 用unionid换取userid

    ding_client = SecretClient(corp_id=DINGTALK_CORP_ID,corp_secret=DINGTALK_CORP_SECRET)
    # 这块提醒下一定要做缓存,由于我之前没做缓存,超过钉钉使用频率而被限制了,修改下上面那句代码
    import redis
    from dingtalk.storage.kvstorage import KvStorage# redis做缓存
    redis_ding = redis.StrictRedis(REDIS_HOST, REDIS_PORT, db=0)
    # 划重点,因为我是第三方web网站,没有使用E应用,所以我的corp_id填的是微应用的id,而不是企业应用ID(corp_id)
    ding_client = SecretClient(corp_id=DINGTALK_APP_KEY,corp_secret=DINGTALK_CORP_SECRET,storage=KvStorage(redis_ding))userid = ding_client.user.get_userid_by_unionid(unionid)
    
  5. userid换取user详情

    user = ding_client.user.get(userid["userid"])
    

二. 加解密

  • 应用场景: 钉钉回调事件
  • 流程:注册回调事件—>处理事件内容(新增员工、更新部门等),返回钉钉加密json

就是说你调用注册事件API,钉钉会给你需要注册的url发送一个post请求,你得按要求返回success,否则注册失败

1.注册事件

再看看什么是success的加密json数据

如果你没有看懂的话,很巧 我也看不懂…

json数据包含这些参数

时间戳和nonce容易拿,问题在于encryptmsg_signature的生成

因为钉钉没有提供python的加解密库,所以看到这块我有点懵

钉钉的文档看不太懂…

百度搜了下 发现有人自己封装了这个库,我看了下名字XXXcryptocrypto这个单词好像在sdk里边见过。

看了sdk目录,果然,虽然钉钉sdk虽然没写关于加解密的内容,但是它其实已经封装了这个库

使用

from dingtalk.crypto import DingTalkCryptoclass Crypto(object):def __init__(self):# 随便填的字符串self.token = DINGTALK_TOKEN# 自己生成的43位随机字符串self.aes_key = DINGTALK_AES_TOKEN# 钉钉企业IDself.corpid = DINGTALK_APP_IDself.crypto = DingTalkCrypto(token=self.token,encoding_aes_key=self.aes_key,corpid_or_suitekey=self.corpid)

说明

原本是不需要自己封装的。看dingtalk的源码

在开始定义ding_client的时候,只需要填参数就可以,经过我反复的调试,发现因为我开发的是企业内部应用-微应用,而不是E应用,所以这里填的corp_id其实是微应用app_key,参数不正确导致后边调试一直返回文本非success错误,为了不与上边填的参数冲突,所以自己封装Crypto类,填写的corp_id是企业应用id

封装好Crypto这个类,就可以调用啦, 先测试返回给钉钉的结果是否正确

from ... import Cryptoclass EventCallBack(Resource):def __init__(self):self.crypto = Crypto().cryptodef post(self):# 返回加密successresult = self.crypto.encrypt_message(msg="success",nonce="123456",timestamp=int(time.time()*1000))return result

事情没这么容易结束…

这个post方法你需要对回调事件作出处理而不是仅仅返回success,所以最终需要这样, 对结果进行处理

    def post(self):po = request.json["encrypt"]data = request.values# 返回加密successresult = self.crypto.encrypt_message(msg="success",nonce="123456",timestamp=int(time.time()*1000))# 获取到事件及其他信息callback = self.crypto.decrypt_encrypt_str(encrypt_str=po,nonce=data["nonce"],timestamp=data["timestamp"],signature=data["signature"])# demjson可以把字符串转为字典,否则取值失败# 安装 pip install demjsoncallback = demjson.decode(callback)# 判断事件类型,作出相应回调if callback["EventType"] == "user_add_org":# 添加员工...elif callback["EventType"] == "org_dept_create":# 添加部门...return result

三. 调试

# 钉钉内网穿透工具,主要作用是方便本地调试需要回调域名的接口
# 地址: https://open-doc.dingtalk.com/microapp/debug/ucof2g
可以后台启动

python项目对接钉钉SDK相关推荐

  1. python项目对接腾讯云发送短信

    python项目对接腾讯云发送短信 先安装需要的包 pip install tencentcloud-sdk-python # -*- coding: utf-8 -*- # pip install ...

  2. Python项目对接CAS

    Python项目对接CAS方案: https://github.com/cameronbwhite/Flask-CAS https://github.com/cameronbwhite/flask-c ...

  3. Python项目对接CAS方案

    https://github.com/cameronbwhite/Flask-CAS https://github.com/cameronbwhite/flask-cas-extension-demo ...

  4. python小项目实例流程-公司内项目对接钉钉审批流程(python)

    1 importrequests2 importjson3 importtime4 from dingtalk.crypto importDingTalkCrypto5 6 from django.c ...

  5. 怎么用python编写个apk_【android】如何利用python做Android项目自动化构建,并一键实现构建结果发送到钉钉通知以及通过二维码下载apk或者其他处理等功能...

    今天我们来谈一谈用python做Android项目自动化构建的过程.我们知道在常规的Android开发过程中,开发人员打包的时候需要在Android Studio当中进行,或者通过gradle命令,但 ...

  6. 项目实践-SpringBoot项目对接钉钉发送工作通知

    项目实践-SpringBoot项目对接钉钉发送工作通知 **书山有路勤为径,学海无涯苦作舟** 记录程序员生活点点滴滴,希望记录的内容能帮助到努力爬山的各位伙伴!标签:Java/钉钉/工作通知 前言 ...

  7. 项目对接浙政钉发送工作消息到浙政钉用户

    项目对接浙政钉发送工作消息到浙政钉用户 一:项目背景 项目需要将设备采集的异常信息,推送给浙政钉的运维用户. 二对接浙政钉消息组件 首先需要注册isv,注册地址为 专有钉钉门户 (dg-work.cn ...

  8. java集成钉钉sdk_JAVA maven项目使用钉钉SDK获取token、用户

    本文介绍了JAVA maven项目使用钉钉SDK获取token.用户,分享给大家,具体如下: 将SDK放一个文件里,记住文件地址.D:\eclipse-workspace\项目名\模块名\lib wi ...

  9. java 钉钉获取用户信息,JAVA maven项目如何使用钉钉SDK来获取token、用户

    JAVA maven项目如何使用钉钉SDK来获取token.用户 发布时间:2020-07-17 10:52:32 来源:亿速云 阅读:102 作者:小猪 这篇文章主要为大家展示了JAVA maven ...

最新文章

  1. 欢迎大家批评:CSDN Blog用户体验调查
  2. 上课讲到的设计模式总结
  3. Java中的static关键字详解
  4. Charles调试Https iOS
  5. 2019ICPC(上海) - Color Graph(二分图+状态压缩)
  6. 每日站立会议(第六天)
  7. 调查显示企业对 Linux 开发人才需求日渐增长
  8. python 判断当前系统的Python编译器类型
  9. linux c程序调用脚本,C程序与Lua脚本相互调用
  10. Error: Cannot find module ‘node-sass‘---Node-sass下载
  11. angular自带的一些api_Angular2.0正式版api使用漫谈
  12. mysql ON DUPLICATE KEY UPDATE重复插入时更新
  13. Linux学习笔记5 - Shell编程(类似于Windows下的批处理)
  14. win8计算机修改mac,快捷MAC地址修改器
  15. 如何破解校园网wifi?怎样破解校园网不能共享wifi?校园网路由器如何破解?
  16. 基于SSM框架的考勤签到请假系统
  17. C语言数据结构与算法-------查找(二)哈希法
  18. 关于百度有啊的几点看法
  19. 番茄花园洪磊,究竟错在哪里?
  20. 论文推荐-计算机视觉

热门文章

  1. 学渣之路:一个月拯救我英语四级
  2. 冈萨雷斯图像处理---非锐化掩蔽和高提升滤波
  3. php 查询功能,php实现查询功能(数据访问)
  4. html5中分镜图文脚本,抖音分镜脚本这样做 轻松打造100w+粉丝大号
  5. 计算机网络实验一层二叉树,2016考研计算机冲刺考点梳理:二叉树算法(1)
  6. 显示pycharm地图
  7. LaTex(windet及miktex)安装教程
  8. 浏览器被恶意设置主页http://www.2345.com/?kunown的解决方法
  9. 出圈问题(java)-----n个人围成一圈,数到key或者key的倍数,出圈,问剩下的最后一个人原来的位置是多少?
  10. 万字长文浅析:Epoll的那些事儿