def refresh_token(): # 通过com_access_token刷新公众号/小程序接口调用凭据/令牌 # 刷新刷新令 com_access_token = dao_wxapi.read_data("com_access_token") appid = config.WXAPPID user_info_list = dao_wxapi.read_info() for user_info in user_info_list: authorizer_appid = user_info["appid"] authorizer_refresh_token = user_info.get("authorizer_refresh_token") data = { "component_appid": appid, "authorizer_appid": authorizer_appid, "authorizer_refresh_token": authorizer_refresh_token } url_refresh_token = config.URL_REFRESH_TOKEN.format(com_access_token) dict_data = request("POST", url_refresh_token, data) if "authorizer_access_token" in dict_data: authorizer_access_token = dict_data["authorizer_access_token"] dao_wxapi.save("authorizer_access_token", authorizer_access_token) authorizer_refresh_token = dict_data["authorizer_refresh_token"] dao_wxapi.save("authorizer_refresh_token", authorizer_refresh_token) user_info_dict = {} user_info_dict["authorizer_access_token"] = authorizer_access_token user_info_dict[ "authorizer_refresh_token"] = authorizer_refresh_token user_info_dict["expires_ts"] = int(time.time()) + int( dict_data["expires_in"]) - 11 * 60 dao_wxapi.update_access_token(authorizer_appid, user_info_dict) else: log_error("refresh_token error: {}".format(str(user_info))) logger.info("refresh_token Done")
def do_auth(inputs: dict, test: bool = False) -> dict: """授权前置步骤""" fail = [] log_info("GET INPUT", inputs) app_id = inputs.get("app_id") rsp = {"sign": 0, "msg": ''} if app_id: # 存入数据库占位, 授权完成后调取信息补位 if inputs.get("pre_auth_code") or test: placeholder = { "pre_auth_code": inputs["pre_auth_code"], "appid": app_id, "nick_name": "_placeholder", "wechat_appid": "_placeholder" } save_rsp = dao_wxservice.save(placeholder) dao_wxapi.save(inputs["pre_auth_code"], app_id) send_log( "AuthorizationStart: placeholder: {}, save_rsp: {}".format( str(placeholder), str(save_rsp))) rsp = save_rsp else: rsp["msg"] = "params loss: app_id" fail.append(rsp["msg"]) return fail, rsp
def com_access_token(): # 通过ticket 获取第三方接口调用凭据 ticket = dao_wxapi.read_data("ticket") data = { "component_appid": appid, "component_appsecret": appsecret, "component_verify_ticket": ticket } url_com_access_token = config.URL_COM_ACCESS_TOKEN dict_data = request("POST", url_com_access_token, data) com_access_token = dict_data["component_access_token"] dao_wxapi.save("com_access_token", com_access_token)
def pre_auth_code(): # 通过com_access_token获取预授权码 com_access_token = dao_wxapi.read_data("com_access_token") data = {"component_appid": appid} url_pre_auth_code = config.URL_PRE_AUTH_CODE.format(com_access_token) dict_data = request("POST", url_pre_auth_code, data) pre_auth_code = dict_data.get("pre_auth_code") or '' if not pre_auth_code: log_error( "pre_auth_code get failed: appid: {}, com_access_token: {}".format( appid, com_access_token)) dao_wxapi.save("pre_auth_code", pre_auth_code) return pre_auth_code
def do_authorization(data_dict): """授权事件处理""" if "AppId" in data_dict: try: appid = data_dict.get("AppId") # 第三方平台Appid authorizer_appid = data_dict.get("AuthorizerAppid") # 公众号appid pre_auth_code = data_dict.get("PreAuthCode") authorization_code = data_dict.get("AuthorizationCode") dao_wxapi.save("auth_code", authorization_code) dao_wxapi.save(authorization_code, pre_auth_code) com_access_token = dao_wxapi.read_data("com_access_token") if not com_access_token: send_log("com_access_token error", err=True) if data_dict.get("InfoType") != "component_verify_ticket": WechatOffAccPlatformMonitor.authorization_event( data_dict.get("InfoType"), data_dict) if data_dict.get("InfoType") == "authorized": # 授权成功 send_log("AuthorizedInfo: " + str(data_dict)) rsp_dict = authorization.authorizer_access_token( authorization_code) if rsp_dict.get("sign"): rsp_dict["msg"] = "授权成功" else: rsp_dict["msg"] = "授权失败" log_error("授权失败|授权信息: {}".format(str(data_dict))) elif data_dict.get("InfoType") == "unauthorized": # 取消授权 send_log("UnauthorizedInfo: " + str(data_dict)) # server_account_info 和 appid_map 中状态置0。 rsp_dict = authorization.unauthorized(authorizer_appid) if rsp_dict["sign"]: rsp_dict["msg"] = "已取消授权" elif data_dict.get("InfoType") == "updateauthorized": # 更新授权 send_log("UpdateauthorizedInfo: " + str(data_dict)) rsp_dict = authorization.authorizer_access_token( authorization_code, False) if rsp_dict["sign"]: update_list = authorization.refresh_info() except Exception as e: send_log(e.__class__.__name__ + '|' + str(e), err=True) return 1
def ticket(): """微信公众号后台自动调用,每十分钟一次""" try: postdata, msg_signature, timestamp, nonce, auth_code, ex = get_paras() postdata = access.decryption(postdata, msg_signature, timestamp, nonce) data_dict = postdata.get("xml") ticket = data_dict.get("ComponentVerifyTicket") dao_wxapi.save("nonce", nonce) if ticket: dao_wxapi.save("ticket", ticket) # 使用ticket更新com_access_token authorization.com_access_token() # 授权处理 sign = do_authorization(data_dict) # 授权事件处理 except Exception as e: send_log(e.__class__.__name__ + '|' + str(e), err=True) return Response('success')
def do_authorizer_access_token(dict_data: dict, auth_code: str, set_map: bool = True, test_data: dict = {}) -> dict: rsp_dict = {"sign": 0, "msg": ''} com_access_token = dao_wxapi.read_data("com_access_token") authorizer_appid = dict_data["authorization_info"]["authorizer_appid"] dao_wxapi.save("authorizer_appid", authorizer_appid) authorizer_access_token = dict_data["authorization_info"][ "authorizer_access_token"] dao_wxapi.save("authorizer_access_token", authorizer_access_token) authorizer_refresh_token = dict_data["authorization_info"][ "authorizer_refresh_token"] dao_wxapi.save("authorizer_refresh_token", authorizer_refresh_token) auth_ex = int(dict_data["authorization_info"]['expires_in']) # 顺便获取授权方的账号基本信息 #头像、昵称、账号类型、认证类型、微信号、原始ID和二维码URL url_getinfo = config.URL_GETINFO.format(com_access_token) data_info = { "component_appid": appid, "authorizer_appid": authorizer_appid } info_dict_data = request("POST", url_getinfo, data_info) send_log("AuthorizationAccountInfoDetail:" + str(info_dict_data)) auth_info_all = '' if ("authorizer_info" in info_dict_data) or test_data: if "authorizer_info" in test_data and "authorization_info" in test_data: info_dict_data = test_data auth_info_all = json.dumps(info_dict_data, ensure_ascii=False) auth_info = info_dict_data["authorizer_info"] nick_name = auth_info["nick_name"] service_type_info = int(auth_info["service_type_info"]["id"]) verify_type_info = int(auth_info["verify_type_info"]["id"]) user_name = auth_info["user_name"] principal_name = auth_info["principal_name"] qrcode_url = auth_info["qrcode_url"] expire_ts = int(time.time()) + auth_ex - 11 * 60 else: nick_name = '' # auth_info["nick_name"] service_type_info = '' # int(auth_info["service_type_info"]["id"]) verify_type_info = '' # int(auth_info["verify_type_info"]["id"]) user_name = '' # auth_info["user_name"] principal_name = '' # auth_info["principal_name"] qrcode_url = '' # auth_info["qrcode_url"] expire_ts = 0 log_error("获取信息失败: wxappid: {}, info_dict_data: {}".format( authorizer_appid, str(info_dict_data))) logger.info("获得授权方账号信息|%s|%s", nick_name, principal_name) if service_type_info != 2: # 2 表示服务号 logger.info("接入的公众号不是服务号|%s|%s", nick_name, principal_name) else: logger.info("接入的公众号是服务号|%s|%s", nick_name, principal_name) if verify_type_info == -1: logger.warning("接入的公众号未经认证|%s|%s", nick_name, principal_name) # 接入服务号到本服务器 # 存储 save_info_data = { "appid": authorizer_appid, "authorizer_access_token": authorizer_access_token, "authorizer_refresh_token": authorizer_refresh_token, "expires_ts": expire_ts, "nick_name": nick_name, "user_name": user_name, "principal_name": principal_name, "qrcode_url": qrcode_url, } insert_id = dao_wxapi.save(authorizer_appid, save_info_data) send_log("AuthorizationAccountSaveBaseInfo|insert_id: {}".format( str(insert_id))) if insert_id and set_map: # 基本信息插入成功,并且需要建立两方appid map pre_auth_code = dao_wxapi.read_data(auth_code) or '' log_info("get_pre_code_back: {}".format(auth_code)) auth_info_data = { "pre_auth_code": pre_auth_code, "wechat_appid": authorizer_appid, "nick_name": nick_name, "auth_info": auth_info_all, } insert_id2_dict = dao_wxservice.update_auth_info(auth_info_data) send_log("AuthorizationAccountSaveInfoDetail|inser_dict: {}".format( str(insert_id2_dict))) if not insert_id2_dict.get("sign"): send_log("Authorized_Update_Map_Error") retry_appid = dao_wxapi.read_data(pre_auth_code) or pre_auth_code retry_auth_info_data = { "appid": retry_appid, "pre_auth_code": pre_auth_code, "wechat_appid": authorizer_appid, "nick_name": nick_name, "auth_info": auth_info_all, } send_log("Retry_Save: {}".format(str(retry_auth_info_data)), err=True) if retry_appid and authorizer_appid and pre_auth_code: # 删除占位,重新写入 del_data1 = dao_wxservice.get_auth_info(retry_appid, '') del_data2 = dao_wxservice.get_auth_info('', pre_auth_code) send_log("Del_Data: del_data1: {}, del_data2: {}".format( str(del_data1), str(del_data2)), err=True) dao_wxservice.real_delete_by(retry_appid, pre_auth_code) dao_wxservice.save(retry_auth_info_data) if not insert_id2_dict.get("sign"): log_error(rsp_dict["msg"]) rsp_dict[ "msg"] = "update_auth_info error. auth_info_data: {}".format( auth_info_data) if insert_id: # pre_auth_code, 一个预授权码,只能被一个公众号接入, 但blueprints中保证了每次都会新生成一个pre_auth_code rsp_dict["sign"] = 1 return rsp_dict