图像

微信公众号第三方平台开发python教程 Part 7

github地址:cppfun@wechat-open-third-party-dev
在本节之前,你需要先阅读前面几节:
微信公众号第三方平台开发python教程 Part 1
微信公众号第三方平台开发python教程 Part 2
微信公众号第三方平台开发python教程 Part 3
微信公众号第三方平台开发python教程 Part 4
微信公众号第三方平台开发python教程 Part 5
微信公众号第三方平台开发python教程 Part 6
本节我们将介绍获取微信服务器推送授权的相关通知。

当公众号对第三方平台进行授权、取消授权、更新授权后,微信服务器会向第三方平台方的授权事件接收URL(创建第三方平台时填写)推送相关通知。

我们在第一节新建应用时应该注意到一个地址:

# 授权事件接收URL
# http://wx.domain.com/auth

所以我们要基于这个地址做点事情,我们来看我们做的事情:

def auth(request):
    if request.method == 'GET':
        json_file = open('com_ticket.json')
        data = json.load(json_file)
        json_file.close()
        if data['ComponentVerifyTicket'] == '':
            return
        ComponentVerifyTicket = data['ComponentVerifyTicket']
        wxOpenSDK = WxOpenSDK(ticket=ComponentVerifyTicket)
        pre_auth_code = wxOpenSDK.get_pre_auth_code()
        redirect_uri = "http://%s/auth" % request.get_host()
        url = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?"
        params = {"component_appid": wxOpenSDK.component_appid,
                  "pre_auth_code": pre_auth_code,
                 "redirect_uri": redirect_uri}
        url = url + urlencode(params)
        return HttpResponseRedirect(url)
    else:
        wxOpenCallBack = WxOpenCallback()
        is_valid = wxOpenCallBack.check_signature(request.GET)
        if is_valid:
            # get the url params
            msg_signature = request.GET.get('msg_signature', '')
            timestamp = request.GET.get('timestamp', '')
            nonce = request.GET.get('nonce', '')

            # get the xml
            encrypt_xml = smart_str(request.body)
            decryp_xml = WxUtils.get_decrypt_xml(encrypt_xml=encrypt_xml,
                                                 msg_signature=msg_signature,
                                                 timestamp=timestamp,
                                                 nonce=nonce)
            if len(decryp_xml) != 0:
                ticket_xml = etree.fromstring(decryp_xml)
                infoType = ticket_xml.find('InfoType').text
                if infoType == 'component_verify_ticket':
                    data = {'ComponentVerifyTicket': ticket_xml.find('ComponentVerifyTicket').text}
                    json_file = open('com_ticket.json', 'w')
                    json_file.write(json.dumps(data))
                    json_file.close()
                elif infoType == 'unauthorized':
                    authorizerAppid = ticket_xml.find('AuthorizerAppid').text
                    authorization_info = get_object_or_404(Authorization_info, authorizer_appid=authorizerAppid)
                    authorization_info.is_authorized = False
                    authorization_info.save()
                elif infoType == 'authorized':
                    # load file
                    json_file = open('com_ticket.json')
                    data = json.load(json_file)
                    json_file.close()

                    if data['ComponentVerifyTicket'] == '':
                        return

                    ComponentVerifyTicket = data['ComponentVerifyTicket']
                    wxOpenSDK = WxOpenSDK(ticket=ComponentVerifyTicket)

                    authorizerAppid = ticket_xml.find('AuthorizerAppid').text
                    authorizationCode = ticket_xml.find('AuthorizationCode').text
                    codeExpiredTime = ticket_xml.find('AuthorizationCodeExpiredTime').text
                    now = time.time()
                    now = int(now)+7000
                    info = wxOpenSDK.get_authorization_info(authorization_code=authorizationCode)

                    authorization_info = Authorization_info(is_authorized=True,
                                                            authorizer_appid=authorizerAppid,
                                                            authorizer_access_token=info['authorizer_access_token'],
                                                            token_expires_time=now,
                                                            authorizer_refresh_token=info['authorizer_refresh_token'],
                                                            authorization_code=authorizationCode,
                                                            code_expires_time=codeExpiredTime)
                    authorization_info.save()
                elif infoType == 'updateauthorized':
                    authorizerAppid = ticket_xml.find('AuthorizerAppid').text
                    authorizationCode = ticket_xml.find('AuthorizationCode').text
                    codeExpiredTime = ticket_xml.find('AuthorizationCodeExpiredTime').text
                    authorization_info = get_object_or_404(Authorization_info, authorizer_appid=authorizerAppid)
                    authorization_info.authorization_code=authorizationCode
                    authorization_info.code_expires_time=codeExpiredTime
                    authorization_info.save()
        return HttpResponse("success")

以上代码在get请求中有个小的缺陷,大家自己去摸索,很好解决,参考如下说明就可以解决。

授权流程完成后,授权页会自动跳转进入回调URI,并在URL参数中返回授权码和过期时间(redirect_url?auth_code=xxx&expires_in=600)

在post中我们其实只做了两件事情,获取ComponentVerifyTicket和接收微信服务器推送授权的相关通知。
这里面包含了解密,这个在第一节已经讲过,然后是针对授权、取消授权、更新授权三种类型事件的处理。代码是很好理解的。
在授权事件的处理中,我们要将授权的信息存储进数据库,为什么这样做?因为你的应用不仅对一个公众号开发,如果只是一个那存在哪里都可以。
在取消授权和重新授权时,我们要更新已有的授权信息,上面的代码有一个缺陷,我已经修复了,大家可以仔细看看缺陷在哪?就当大家自己思考的一个过程。
如果你真的只是copy代码,那么我其实也帮不了你。
后面的教程应该还有两节内容,下一节我准备讲讲《全网发布接入检测》这个环节。

发表评论