Django及钉钉实现第三方登录

所有第三方登录都要先获取第三方应用的Id和秘钥
开发之前,需要前往第三方登录的开发者平台QQ、新浪微博、Github,注册账号并填写信息申请接入,成功后会给你一个ID和秘钥,以后你就通过该ID和秘钥来获取令牌,从而实现第三方登录。申请ID和秘钥时Github不需要审核,很简单,而QQ和新浪微博需要审核,稍微麻烦一点。
获得ID和秘钥后需要在setting中进行设置
以钉钉登录为例:关键点就是获取到钉钉的凭证appid,然后将appid跟我们的用户模型联系起来。

这是钉钉的开发者文档:我们应先做好准备工作,可以借鉴以下文档,完成前期准备工作http://wiki.connect.qq.com/准备工作_oauth2-0事件订阅 - 钉钉开放平台钉钉会向应用推送订阅的事件,例如部门变更、签到通知、打卡通知等。通过订阅这些事件,可以更好地与钉钉集成。你只需告诉钉钉当某个事件发生时,钉钉需要推送消息到哪个URL,钉钉会以HTTPhttps://open.dingtalk.com/document/org/push-eventshttp://wiki.connect.qq.com/准备工作_oauth2-0 第三方登录都有其相应的开发者文档。

我们先用一张流程图来简单了解一下钉钉第三方登录都需要做什么,为我们写代码,带来一些思路

Django及钉钉实现第三方登录_第1张图片

 图画的不是太好,但是基本还是可以帮我们理解一下第三方登录流程,以及梳理第三方登录的思路。

我们先把前端写一下,前端生成二维码

前端

    



    // 钉钉登录
    dingding: function () {
      var appid = "dingoajf8cqgyemqarekhr";
      var redirect_uri = 'http://127.0.0.1:8080/' + "dingding";

      var url =
        "https://oapi.dingtalk.com/connect/qrconnect?appid=" +
        appid +
        "&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" +
        redirect_uri;
      window.open(url, "_blank");
      window.location.href = url;
    },

 appid需要我们自己去钉钉的开发者文档去注册,获取到appid之后我们就可以生成钉钉第三方登录的二维码了

Django及钉钉实现第三方登录_第2张图片

 如上图所示

接下来我们来写一下钉钉扫码之后的逻辑,是否绑定已经注册的用户


重点以及难以理解的代码,上边都有注释,在此就不一一解释

后端

首先我们定义一下模型类

class OauthUser(models.Model):
    """
    第三方登录表(微信登录/qq登录/微博登录)
    """
    __tablename__ = 'oauth_user'
    image = models.CharField(max_length=255, verbose_name='头像', unique=True, null=True)
    uid = models.CharField(max_length=255, verbose_name='第三方登录的id', unique=True, null=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    oauth_type = models.CharField(max_length=255, verbose_name='第三方登录类型')

    class Meta:
        db_table = 'oauth_user'

    def __str__(self):
        return self.uid

定义好模型类之后我们就可以进行下边的逻辑代码的实现

class DingDingCallBack(APIView):
    """
    钉钉三方登录回调
    """

    def post(self, request):
        # 获取code
        code = request.data.get('code')
        t = time.time()
        # 时间戳
        timestamp = str((int(round(t * 1000))))
        appSecret = 'Fcah25vIw-koApCVN0mGonFwT2nSze14cEe6Fre8i269LqMHRI2Mu9VK'
        # 构造签名
        signature = base64.b64encode(
            hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())
        # 请求接口,换取钉钉用户名
        payload = {'tmp_auth_code': code}
        headers = {'Content-Type': 'application/json'}
        res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(
            signature.decode("utf-8")) + "×tamp=" + timestamp + "&accessKey=dingoajf8cqgyekhr",
                            data=json.dumps(payload), headers=headers)
        res_json = res.json()
        if res_json['errcode'] != 0:
            return {'message': res_json['errmsg'], 'code': 500, 'data': {'uid': '110'}}
        unid = res_json['user_info']['unionid']
        # 查找用户是否已经添加绑定关系
        user = OauthUser.objects.filter(uid=unid).first()
        if user:
            # 用户已经添加绑定关系
            if user.user:
                # 直接返回主页面
                return Response({'message': 'ok', 'code': 200, 'data': res})
        return Response({'message': 'Not bind account', 'code': 201, 'data': unid})

在这里我们在扫码之后要判断用户是否已经绑定了已经注册的用户,如果没有就然后用户绑定一下,如果已经绑定就直接登录成功

下边就是绑定用户的一些代码

class BindDingDing(APIView):
    """
    绑定钉钉账号
    """

    def post(self, request):
        unid = request.data.get('unid')
        username = request.data.get('username')
        password = request.data.get('password')
        user = User.objects.get(username=username)
        rest = check_password(password, user.password)
        if not rest:
            return Response({'message': '账号密码错误', 'code': 405})
        oauth = OauthUser.objects.filter(uid=unid).first()
        if oauth:
            return Response({'message': '该用户已经绑定,无法重复绑定', 'code': 403})
        dingding = '钉钉'
        users = User.objects.get(username=username)
        dingding = OauthUser.objects.create(user=users, uid=unid, oauth_type=dingding)
        dingding.save()
        data = [{
            'username': username, 'id': unid
        }]
        return Response({'message': '绑定成功', 'code': 200, 'data': data})

在此代码中,我们也得进行一些必要的判断

以上就是django配合vue以及钉钉实现的第三方登录,希望可以帮到屏幕前的你

你可能感兴趣的:(django,python,后端)