• 基础类封装-解决系统token刷新机制带来的token变更问题


    背景:

    当前测试系统token存在刷新机制,每隔20min刷新一个最新的token,当在接口测试过程中,长时间运行导致登录的token失效

    刷新机制:登录系统后获取一个toekn_A,15min后刷新一个token_B,20min以内token_A和token_B都生效,20min后token_A失效,token_B生效(以此循环),故为此需要解决自动化测试过程中的token刷新机制

    解决思路:

    1.将登录后返回的token_A存放到测试环境的数据库中

    2.主进程在运行过程中开启一个子线程去请求心跳接口,按心跳间隔获取最新的token_B信息,如果token_A等于token_B则不更新数据,反之则将最新的token_B存放到数据库中

      1 import os
      2 import sys
      3 sys.path.insert(0,os.getcwd())
      4 import time
      5 import json
      6 import threading
      7 from lib.tools import *
      8 from lib.mbh_init_db import *
      9 from lib.logger import logger
     10 from util.encry import md5_key
     11 from interface.tool import Tool
     12 from httprun.HttpRun import HttpRun
     13 from util.RandomStr import RandomStr
     14 from config.VarConfig import cert_file
     15 from config.golbalSetting import hostname,cmapi
     16 
     17 
     18 class CMAPI(threading.Thread):
     19 
     20     # 定义心跳间隔,单位s
     21     interval = 45
     22     # 定义域名信息
     23     domain = cmapi
     24     # 忽略SSL验证
     25     verify = False
     26     # 定义crt证书文件
     27     cert = cert_file
     28     # 定义操作终端
     29     sobeyhive_http_system = getattr(Tool,'sobeyhive_http_system')
     30     # 定义工具类型
     31     sobeyhive_http_tool = getattr(Tool,'sobeyhive_http_tool')
     32     # 定义site
     33     sobeyhive_http_site = getattr(Tool,'sobeyhive_http_site')
     34     # 定义user-agent
     35     user_agent = getattr(Tool,'user_agent')
     36     # 定义数据表的名称
     37     init_table = table_name
     38     # 定义日志
     39     logger = logger
     40 
     41     def __init__(self,username,password):
     42         threading.Thread.__init__(self) # 定义继承类初始化方法
     43         self.username = username
     44         self.password = password
     45         self.httprun = HttpRun().http_run
     46         self.db = initDB()
     47         self.logoutflag = False  # 设置登出标记
     48         self.validuser = False   # 设置用户是否有效
     49         # 定义用户信息
     50         self.logininfoid = None  # 心跳维护使用
     51         self.loginip = None  # 登录ip
     52         self.loginname = None  # 登录用户名
     53         self.sitecode = None  # 多站点
     54         self.usercode = None
     55         self.userid = None
     56         self.usertoken = None
     57         self.organizationcode = None
     58         self.refreshtoken = None  # 定义刷新的totkn,从子线程中获取
     59         # cookies
     60         self.cookies = None
     61 
     62     def login(self):
     63         """
     64         login
     65         :return dict type
     66         """
     67         self.logger.logger.info('当前方法: %s'%p.get_current_function_name())
     68         url = self.domain + "/CMApi/api/basic/account/login"
     69         self.logger.logger.info('请求地址: %s' % url)
     70         headers = {
     71             "Content-Type": "application/json"
     72         }
     73         self.logger.logger.info('请求头: %s' % headers)
     74         passwd = md5_key(self.password) if self.password else None
     75         playload = {
     76             "LOGINNAME": self.username,
     77             "LOGINPWD": passwd,
     78             "LOGINSUBSYSTEM": self.sobeyhive_http_system['WEBCM'],
     79             "LOGINIP": RandomStr.generate_uuid()
     80         }
     81         self.logger.logger.info('请求参数: %s' % playload)
     82         try:
     83             response = self.httprun(method='post', url=url, data=json.dumps(playload), headers=headers,verify=self.verify)
     84             if response is None:
     85                 sys.exit('login response is None,Please Check environment!')
     86             res = response.json()
     87             if res['code'] == '0':
     88                 setattr(self, 'logininfoid', res['ext']['logininfoid'])
     89                 setattr(self, 'loginip', res['ext']['loginip'])
     90                 setattr(self, 'loginname', res['ext']['loginname'])
     91                 setattr(self, 'sitecode', res['ext']['organizations'][0]['sitecode'])
     92                 setattr(self, 'usercode', res['ext']['usercode'])
     93                 setattr(self, 'userid', res['ext']['userid'])
     94                 setattr(self, 'usertoken', res['ext']['usertoken'])
     95                 setattr(self, 'organizationcode', res['ext']['organizations'][0]['organizationcode'])
     96                 setattr(self, 'cookies', response.cookies)
     97                 # print(json.dumps(re,indent=2,ensure_ascii=False))
     98                 # 存储用户名及token,用户后续的心跳更新,先判断表中是否存在token,存在则更新,不存在则插入
     99                 query_sql = "select username from {0} where username = '{1}'".format(self.init_table,self.username)
    100                 result = self.db.query_db(query_sql,state="all")
    101                 if isinstance(result,tuple) and len(result)==0:
    102                     insert_sql = "insert into {0} value('{1}','{2}');".format(self.init_table, self.loginname, self.usertoken)
    103                     self.db.execute_db(insert_sql)
    104                 else:
    105                     if self.username in result[0].get('username'):
    106                         updata_sql = "update {0} set usertoken = '{1}' where username='{2}'".format(self.init_table,self.usertoken,self.username)
    107                         self.db.execute_db(updata_sql)
    108             else:
    109                 self.logger.logger.info('请求耗时: %s 毫秒' % (int(response.elapsed.microseconds) // 1000))
    110                 self.logger.logger.error('登录失败,Status Code: %s'% response.status_code)
    111                 return res
    112         except Exception as e:
    113             self.logger.logger.exception(e)
    114             return None
    115         else:
    116             self.logger.logger.info('请求耗时: %s 毫秒'%(int(response.elapsed.microseconds)//1000))
    117             self.logger.logger.info('响应结果: %s' % res)
    118             self.validuser = True
    119             return res
    120 
    121     def testfunctionpopedom(self):
    122         """判断登录权限"""
    123         self.logger.logger.info('当前方法: %s' % p.get_current_function_name())
    124         if self.validuser:
    125             usertoken = self.get_token()
    126             url = self.domain + "/CMApi/api/basic/account/testfunctionpopedom?usertoken={0}".format(usertoken)
    127             self.logger.logger.info('请求地址: %s' % url)
    128             headers = {
    129                 "Content-Type": "application/json",
    130                 "sobeyhive-http-site": self.sitecode,
    131                 "sobeyhive-http-system": CMAPI.sobeyhive_http_system['WEBCM'],
    132                 "sobeyhive-http-token": usertoken,
    133                 "sobeyhive-http-tool": CMAPI.sobeyhive_http_tool['WEBCM'],
    134                 "sobeyhive-http-usercode": self.usercode
    135             }
    136             self.logger.logger.info('请求头: %s' % headers)
    137             payload = [
    138                 {
    139                     "system":"WEBCM",
    140                     "tool":"DEFAULT",
    141                     "popedomname":"CANUSEWEBCM"
    142                 }
    143             ]
    144             try:
    145                 response = self.httprun('post', url, headers=headers, data=json.dumps(payload),verify=self.verify)
    146                 res = response.json()
    147             except Exception as e:
    148                 self.logger.logger.exception(e)
    149             else:
    150                 self.logger.logger.info('请求耗时: %s 毫秒' % (int(response.elapsed.microseconds) // 1000))
    151                 self.logger.logger.info('响应结果: %s' % res)
    152                 return res
    153         else:
    154             return
    155 
    156     def heartbeat(self):
    157         """
    158         cmapi心跳接口
    159         :return:
    160         """
    161         self.logger.logger.info('当前方法: %s' % p.get_current_function_name())
    162         usertoken = self.get_token()
    163         if self.validuser:
    164             url = self.domain + "/CMApi/api/basic/account/heatbeat?loginInfoID={0}&systemtype=WEBCM".format(self.logininfoid)
    165             self.logger.logger.info('请求地址: %s' % url)
    166             headers = {
    167                 "Content-Type": "application/json",
    168                 "sobeyhive-http-site": self.sitecode,
    169                 "sobeyhive-http-system": CMAPI.sobeyhive_http_system['WEBCM'],
    170                 "sobeyhive-http-token": usertoken,
    171                 "sobeyhive-http-tool": CMAPI.sobeyhive_http_tool['WEBCM'],
    172                 "sobeyhive-http-usercode": self.usercode
    173             }
    174             self.logger.logger.info('请求头: %s' % headers)
    175             try:
    176                 response = self.httprun('get',url, headers=headers,verify=self.verify)
    177                 res = response.json()
    178                 if response.status_code == 200:
    179                     pass
    180                 else:
    181                     self.logger.logger.error("requests failed! Status Code:", res.status_code)
    182             except Exception as e:
    183                 self.logger.logger.exception(e)
    184             else:
    185                 self.logger.logger.info('请求耗时: %s 毫秒' % (int(response.elapsed.microseconds) // 1000))
    186                 self.logger.logger.info('响应结果: %s' % res)
    187                 return res
    188         else:
    189             return
    190 
    191     def logout(self):
    192         """
    193         cmapi登出接口
    194         :return:
    195         """
    196         self.logger.logger.info('当前方法: %s' % p.get_current_function_name())
    197         url = self.domain + "/CMApi/api/basic/account/logout"
    198         self.logger.logger.info('请求地址: %s' % url)
    199         try:
    200             response = self.httprun(method="get",url=url,verify=self.verify)
    201             res = response.json()
    202             self.logoutflag = True  # 设置登出标志
    203             if res['code'] == "1":
    204                 self.logger.logger.info("登出成功!")
    205                 return True
    206             else:
    207                 return False
    208         except Exception as e:
    209             self.logger.logger.info('请求耗时: %s 毫秒' % (int(response.elapsed.microseconds) // 1000))
    210             self.logger.logger.info('响应结果: %s' % res)
    211             self.logger.logger.exception(e)
    212 
    213     def run(self):
    214         """
    215         开启子线程,按固定间隔获取最新token
    216         :return:
    217         """
    218         while True:
    219             if not self.logoutflag:
    220                 # 设置心跳间隔
    221                 time.sleep(self.interval)
    222                 res = CMAPI.heartbeat(self)
    223                 self.logger.logger.info(res)
    224                 #TODO: 更新token到mysql中,先查询token值
    225                 query_sql = "select usertoken from {0} where username = '{1}'".format(self.init_table,self.username)
    226                 result = self.db.query_db(query_sql)
    227                 if res['ext'] != '':
    228                     if result[0].get('usertoken') != res['ext']:
    229                         update_sql = "update {0} set usertoken = '{1}' where username='{2}'".format(self.init_table,res['ext'],self.username)
    230                         self.db.execute_db(update_sql)
    231                         self.refreshtoken = res['ext']
    232                 else:
    233                     self.logger.logger.error("token更新失败:",res)
    234             else:
    235                 break
    236 
    237     def get_token(self):
    238         """获取用户的token信息"""
    239         sql = "select usertoken from {0} where username = '{1}';".format(self.init_table, self.username)
    240         self.db.select_db(db_name)
    241         query_result = self.db.query_db(sql)
    242         if query_result:
    243             return query_result[0].get('usertoken')
    244         else:
    245             return None
    246 
    247 
    248 
    249 
    250 
    251 
    252 
    253 if __name__ == "__main__":
    254     print("父进程PID:%s" % os.getpid())
    255     t = CMAPI('tyw','tyw')
    256     t.login()
    257     t.start() # 开启子进程,当存在token刷新机制时开启
    258     t.testfunctionpopedom()
    259     # t.get_token()
    260     t.logout()
  • 相关阅读:
    拖拽更改窗口大小
    一个窗口移动时,另一个窗口跟随移动
    xcode使用技巧
    同一个解决方案中,多个项目间相互引用,无法打开源文件
    截图时窗口自动识别
    C++使用sqlite时,中文字符显示乱码问题
    sqlite3配置与使用
    duilib控件与属性说明
    xml文件编写
    线程及安全相关
  • 原文地址:https://www.cnblogs.com/tython/p/12701546.html
Copyright © 2020-2023  润新知