django 釘釘掃碼登入
阿新 • • 發佈:2018-11-10
django 釘釘登入
原理
先去獲取釘釘使用者資訊,獲取之後 去django User裡面 查詢 是否存在,不存在就建立,存在就正常登入。
根據唯一ID 進行判斷
登入圖
釘釘部分
請參考如下連結
django部分
login頁面
url 是 登入請求處理頁面
appid 是 釘釘 id
<div id="login_container"></div> <script src="http://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script> <script> var url = encodeURIComponent('http://www.hequan.lol/login-dingding.html'); var goto = encodeURIComponent('https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=xxxxxxxxxxxxxxxxxxxxxxxx&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=' + 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=xxxxxxxxxxxxxxxxxxxxxxxx&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" + url + "&loginTmpCode=" + loginTmpCode; 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>
views.py
appId 和 appSecret 是 釘釘資訊
import requests import random def login_dingding(request): if request.method == "GET": code = request.GET.get('code', ) state = request.GET.get('state', ) appId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx' appSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' token = requests.get(f'https://oapi.dingtalk.com/sns/gettoken?appid={appId}&appsecret={appSecret}') access_token = token.json()["access_token"] tmp_auth_code = requests.post(f"https://oapi.dingtalk.com/sns/get_persistent_code?access_token={access_token}", json={ "tmp_auth_code": code }) tmp_code = tmp_auth_code.json() print(tmp_code) openid = tmp_code['openid'] persistent_code = tmp_code['persistent_code'] sns_token_request = requests.post(f"https://oapi.dingtalk.com/sns/get_sns_token?access_token={access_token}", json={ "openid": openid, "persistent_code": persistent_code }) sns_token = sns_token_request.json()['sns_token'] user_info_request = requests.get(f'https://oapi.dingtalk.com/sns/getuserinfo?sns_token={sns_token}') user_info = user_info_request.json()['user_info'] print(user_info) try: user = User.objects.get(first_name=user_info['unionid']) except Exception as e: password = f'hequan{random.randint(1000,9999)}' try: user = User.objects.create(username=user_info['nick'], password=password, first_name=user_info['unionid']) except Exception as e: user = User.objects.create(username=f"{user_info['nick']}{random.randint(0,9999)}", password=password, first_name=user_info['unionid']) finally: login(request, user) request.session['is_login'] = True login_ip = request.META['REMOTE_ADDR'] LoginLogs.objects.create(user=request.user, ip=login_ip) return redirect('/index.html')