钉钉作为阿里旗下的一款免费移动通讯软件,受众群体越来越多,这里我们使用 Django 来集成一下钉钉的三方账号登录,首先注册钉钉开发平台:https://open-dev.dingtalk.com/

在移动应用中选择登录

使用django钉钉第三方扫码登录 - O泡小涵 - 博客园 - 图1


创建一个网站应用,其中有用的信息是 appid , appsecret ,还有回调网址


使用django钉钉第三方扫码登录 - O泡小涵 - 博客园 - 图2

随后,查看官方文档,查看如何构造登录 url:https://ding-doc.dingtalk.com/doc#/serverapi2/kymkv6

这里我们用 django 视图来操作

  1. def ding_url(request):
  2. appid = 'dingoaukgkwqknzjvamdqh'
  3. redirect_uri = 'http://localhost:8000/dingding_back/'
  4. return redirect('https://oapi.dingtalk.com/connect/qrconnect?appid='+appid+'&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+redirect_uri)

然后访问 http://localhost:8000/ding_url , 就可以进行扫码

随后,钉钉会将 code 返回到回调网址中,查看官方文档,只有 java 和 php 的 sdk,并没有 python 的


SDK 请求示例 (JAVA):

  1. DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/sns/getuserinfo_bycode");
  2. OapiSnsGetuserinfoBycodeRequest req = new OapiSnsGetuserinfoBycodeRequest();
  3. req.setTmpAuthCode("4a2c5695b78738d495f47b5fee9160cd");
  4. OapiSnsGetuserinfoBycodeResponse response = client.execute(req,"yourAppId","yourAppSecret");

SDK 请求示例 (PHP):

  1. include "TopSdk.php";
  2. $c = new DingTalkClient(DingTalkConstant::$CALL_TYPE_OAPI, DingTalkConstant::$METHOD_POST , DingTalkConstant::$FORMAT_JSON);
  3. $req = new OapiSnsGetuserinfoBycodeRequest;
  4. $req->setTmpAuthCode("4a2c5695b78738d495f47b5fee9160cd");
  5. $resp=$c->executeWithAccessKey($req, "https://oapi.dingtalk.com/sns/getuserinfo_bycode","yourAppId","yourAppSecret");
  6. var_dump($resp)

python 逻辑很简单,将时间戳,秘钥进行 hmac 加密即可

  1. import hmac
  2. import base64
  3. from hashlib import sha256
  4. import urllib
  5. import json
  6. def ding_url(request):
  7. appid = 'dingoadckiwhdceemaxrza',
  8. redirect_uri = 'http://127.0.0.1:8000/ding_url'
  9. code = request.GET.get("code")
  10. t = time.time()
  11. timestamp = str((int(round(t * 1000))))
  12. appSecret = 'Uym9ecJfNF4vlQ9-8wAGl2J10GvyZNKJqiXvcuf0blp7ERTpWrif8IwWk_AGI1j-'
  13. signature = base64.b64encode(
  14. hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())
  15. payload = {'tmp_auth_code': code}
  16. headers = {'Content-Type': 'application/json'}
  17. res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(
  18. signature.decode("utf-8")) + "&timestamp=" + timestamp + "&accessKey=dingoadckiwhdceemaxrza",
  19. data=json.dumps(payload), headers=headers)
  20. res_dict = json.loads(res.text)
  21. print(res_dict)

访问一下,可以显示出钉钉的用户名


vue 与 django 结合 钉钉第三放登录

  1. //vue登录页面内点击事件
  2. //钉钉登录
  3. dingding() {
  4. //拼接钉钉url
  5. let url = "https://oapi.dingtalk.com/connect/qrconnect?appid=dingoadckiwhdceemaxrza&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=http://127.0.0.1:8000/ding_url"
  6. //进行站外跳转
  7. window.location.href = url;
  8. },

django 视图页面:

  1. import hmac
  2. import base64
  3. from hashlib import sha256
  4. import urllib
  5. import json
  6. def ding_url(request):
  7. appid = 'dingoadckiwhdceemaxrza',
  8. redirect_uri = 'http://127.0.0.1:8000/ding_url'
  9. code = request.GET.get("code")
  10. t = time.time()
  11. timestamp = str((int(round(t * 1000))))
  12. appSecret = 'Uym9ecJfNF4vlQ9-8wAGl2J10GvyZNKJqiXvcuf0blp7ERTpWrif8IwWk_AGI1j-'
  13. signature = base64.b64encode(
  14. hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())
  15. payload = {'tmp_auth_code': code}
  16. headers = {'Content-Type': 'application/json'}
  17. res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(
  18. signature.decode("utf-8")) + "&timestamp=" + timestamp + "&accessKey=dingoadckiwhdceemaxrza",
  19. data=json.dumps(payload), headers=headers)
  20. res_dict = json.loads(res.text)
  21. user = models.User.objects.filter(username=str(res_dict['user_info']['nick'])).first()
  22. sina_name = ''
  23. user_id = ''
  24. if user:
  25. sina_name = user.username
  26. user_id = user.id
  27. else:
  28. models.User(username=str(res_dict['user_info']['nick']), password=make_password(''), type=0).save()
  29. print('已创建钉钉账户')
  30. user = models.User.objects.filter(username=str(res_dict['user_info']['nick'])).first()
  31. sina_name = res_dict['user_info']['nick']
  32. user_id = user.id
  33. return redirect("http://localhost:8080?sina_name=" + str(sina_name) + "&uid=" + str(user_id))

https://www.cnblogs.com/z-han/p/12810737.html