1. 程式人生 > >django 釘釘掃碼登入

django 釘釘掃碼登入

django 釘釘登入

原理

先去獲取釘釘使用者資訊,獲取之後 去django User裡面 查詢 是否存在,不存在就建立,存在就正常登入。
根據唯一ID 進行判斷

登入圖

django 釘釘掃碼登入

釘釘部分

請參考如下連結

https://open-doc.dingtalk.com/microapp/serverapi2/kymkv6

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