成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)-創(chuàng)新互聯(lián)

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供鹽湖網(wǎng)站建設(shè)、鹽湖做網(wǎng)站、鹽湖網(wǎng)站設(shè)計(jì)、鹽湖網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、鹽湖企業(yè)網(wǎng)站模板建站服務(wù),十余年鹽湖做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
DINGTALK_CORP_ID = "重點(diǎn):企業(yè)應(yīng)用ID"
# 釘釘微應(yīng)用
DINGTALK_APP_KEY = "微應(yīng)用APP_KEY"
DINGTALK_CORP_SECRET = "微應(yīng)用SERCRET"
# 釘釘移動(dòng)應(yīng)用(掃碼登錄),在移動(dòng)應(yīng)用接入菜單里配置
DINGTALK_APP_ID = "移動(dòng)應(yīng)用APP_ID"
DINGTALK_APP_SECRET = "移動(dòng)應(yīng)用APP_SECRET"
# 釘釘aes加密(隨機(jī))
DINGTALK_AES_TOKEN = "43位字符串 a-zA-Z0-9中生成"
DINGTALK_TOKEN = "字符串隨便填"

一. 第三方web網(wǎng)站掃碼登錄1. 流程

釘釘掃碼—>判斷是否公司員工—>登錄

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

關(guān)于web系統(tǒng)的兩種接入方式,都只能獲取到用戶的釘釘身份,并不能獲取到用戶是否在企業(yè)中

解決方法:

批量同步釘釘人員信息到數(shù)據(jù)庫(kù),登錄后匹配數(shù)據(jù)庫(kù),新進(jìn)員工通過(guò)釘釘回調(diào)同步到數(shù)據(jù)庫(kù),回調(diào)未生效人工審核后手動(dòng)更新數(shù)據(jù)庫(kù)

由于釘釘開(kāi)發(fā)文檔讀的不夠仔細(xì)導(dǎo)致調(diào)試頻繁出錯(cuò),所以開(kāi)發(fā)流程我簡(jiǎn)單說(shuō),把細(xì)節(jié)放大

前端導(dǎo)入釘釘scrpit文件開(kāi)發(fā)掃碼頁(yè)面

<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/oauth3/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);
  	//判斷是否來(lái)自ddLogin掃碼事件。
    if( origin == "https://login.dingtalk.com" ) {
      //拿到loginTmpCode后就可以在這里構(gòu)造跳轉(zhuǎn)鏈接進(jìn)行跳轉(zhuǎn)了
      var loginTmpCode = event.data;
      console.log("loginTmpCode", loginTmpCode);
      if(loginTmpCode){
        let uri="https://oapi.dingtalk.com/connect/oauth3/sns_authorize?appid=dingoadwjj1iszubeh9rnf&response_type=code&scope=snsapi_login&state=STATE&redirect_uri="+url+"&loginTmpCode="+loginTmpCode;
        // 跳轉(zhuǎn)
        location.href = uri;
      }
    }
};

if (typeof window.addEventListener != 'undefined') {
  window.addEventListener('message', hanndleMessage, false);
} else if (typeof window.attachEvent != 'undefined') {
  window.attachEvent('onmessage', hanndleMessage);
}
</script>

配置掃碼后跳轉(zhuǎn)頁(yè)面(就是第一步goto參數(shù)里的url),釘釘會(huì)自動(dòng)在跳轉(zhuǎn)頁(yè)面路由后添加codestate參數(shù)

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

拿到code請(qǐng)求后端接口

<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>

后端用appid和appsecret獲取access_token

import requests
from dingtalk.client import SecretClient

class 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"]

用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"]

用unionid換取userid

ding_client = SecretClient(corp_id=DINGTALK_CORP_ID,
               corp_secret=DINGTALK_CORP_SECRET)
# 這塊提醒下一定要做緩存,由于我之前沒(méi)做緩存,超過(guò)釘釘使用頻率而被限制了,修改下上面那句代碼
import redis
from dingtalk.storage.kvstorage import KvStorage

# redis做緩存
redis_ding = redis.StrictRedis(REDIS_HOST, REDIS_PORT, db=0)
# 劃重點(diǎn),因?yàn)槲沂堑谌絯eb網(wǎng)站,沒(méi)有使用E應(yīng)用,所以我的corp_id填的是微應(yīng)用的id,而不是企業(yè)應(yīng)用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)

userid換取user詳情

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

二. 加解密

應(yīng)用場(chǎng)景: 釘釘回調(diào)

事件流程:注冊(cè)回調(diào)事件—>處理事件內(nèi)容(新增員工、更新部門等),返回釘釘加密json

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

就是說(shuō)你調(diào)用注冊(cè)事件API,釘釘會(huì)給你需要注冊(cè)的url發(fā)送一個(gè)post請(qǐng)求,你得按要求返回success,否則注冊(cè)失敗

1.注冊(cè)事件

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

再看看什么是success的加密json數(shù)據(jù)

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

如果你沒(méi)有看懂的話,很巧 我也看不懂…

json數(shù)據(jù)包含這些參數(shù)

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

時(shí)間戳和nonce容易拿,問(wèn)題在于encryptmsg_signature的生成

因?yàn)獒斸敍](méi)有提供python的加解密庫(kù),所以看到這塊我有點(diǎn)懵

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

釘釘?shù)奈臋n看不太懂…

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

百度搜了下 發(fā)現(xiàn)有人自己封裝了這個(gè)庫(kù),我看了下名字XXXcrypto,crypto這個(gè)單詞好像在sdk里邊見(jiàn)過(guò)。

看了sdk目錄,果然,雖然釘釘sdk雖然沒(méi)寫(xiě)關(guān)于加解密的內(nèi)容,但是它其實(shí)已經(jīng)封裝了這個(gè)庫(kù)

使用

from dingtalk.crypto import DingTalkCrypto

class Crypto(object):
  def __init__(self):
    # 隨便填的字符串
    self.token = DINGTALK_TOKEN
    # 自己生成的43位隨機(jī)字符串
    self.aes_key = DINGTALK_AES_TOKEN
    # 釘釘企業(yè)ID
    self.corpid = DINGTALK_APP_ID
    self.crypto = DingTalkCrypto(
      token=self.token,
      encoding_aes_key=self.aes_key,
      corpid_or_suitekey=self.corpid
    )

說(shuō)明

原本是不需要自己封裝的??磀ingtalk的源碼

python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)

在開(kāi)始定義ding_client的時(shí)候,只需要填參數(shù)就可以,經(jīng)過(guò)我反復(fù)的調(diào)試,發(fā)現(xiàn)因?yàn)槲议_(kāi)發(fā)的是企業(yè)內(nèi)部應(yīng)用-微應(yīng)用,而不是E應(yīng)用,所以這里填的corp_id其實(shí)是微應(yīng)用app_key,參數(shù)不正確導(dǎo)致后邊調(diào)試一直返回文本非success錯(cuò)誤,為了不與上邊填的參數(shù)沖突,所以自己封裝Crypto類,填寫(xiě)的corp_id是企業(yè)應(yīng)用id

封裝好Crypto這個(gè)類,就可以調(diào)用啦, 先測(cè)試返回給釘釘?shù)慕Y(jié)果是否正確

from ... import Crypto

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

事情沒(méi)這么容易結(jié)束…

這個(gè)post方法你需要對(duì)回調(diào)事件作出處理而不是僅僅返回success,所以最終需要這樣, 對(duì)結(jié)果進(jìn)行處理

 def post(self):
    po = request.json["encrypt"]
    data = request.values
    # 返回加密success
    result = 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可以把字符串轉(zhuǎn)為字典,否則取值失敗
    # 安裝 pip install demjson
    callback = demjson.decode(callback)
    # 判斷事件類型,作出相應(yīng)回調(diào)
    if callback["EventType"] == "user_add_org":
      # 添加員工
      ...
    elif callback["EventType"] == "org_dept_create":
      # 添加部門
      ...
    return result

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。

網(wǎng)站名稱:python項(xiàng)目對(duì)接釘釘SDK的實(shí)現(xiàn)-創(chuàng)新互聯(lián)
標(biāo)題路徑:http://jinyejixie.com/article8/deddop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站、全網(wǎng)營(yíng)銷推廣、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站策劃服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)
桦南县| 苏州市| 张家港市| 泉州市| 河池市| 资讯 | 临泽县| 古蔺县| 南岸区| 延川县| 台北县| 堆龙德庆县| 崇阳县| 乐昌市| 东莞市| 宜兰县| 安顺市| 博乐市| 津市市| 南乐县| 大城县| 马公市| 临朐县| 达尔| 德保县| 赤壁市| 望奎县| 永宁县| 普宁市| 象山县| 岑溪市| 渭源县| 丘北县| 黑河市| 遂川县| 通城县| 凤山县| 马山县| 德庆县| 老河口市| 河东区|