def decorator(*args, **kw): # 校验参数 try: check_rule = build_check_rule(str(request.url_rule),str(request.rule_version), list(request.url_rule.methods & set(METHODS))) check_func = check_param.get_check_rules().get(check_rule) if check_func: check_func(*args, **kw) except BusinessException as e: if not is_none(e.func): return e.func elif not is_none(e.code) and not is_none(e.msg): business_exception_log(e) return return_data(code=e.code, msg=e.msg) # 监听抛出的异常 try: if request.trace_id is not None and request.full_path is not None: logger.info('trace_id is:' + request.trace_id + ' request path:' + request.full_path) return func(*args, **kw) except BusinessException as e: if e.func is not None: return e.func() elif e.code is not None and e.msg is not None: business_exception_log(e) if e.code == SYSTEM_CODE_404 or e.code == SYSTEM_CODE_503: return return_data(code=e.code, msg='很抱歉服务器异常,请您稍后再试') else: return return_data(code=e.code, msg=e.msg) else: return request_fail() except Exception: return request_fail()
def decorated_function(*args, **kw): #### 所有注释都是进行单点登录操作的 !!!!!!! auth_token = request.cookies.get('auth_token') refresh_time = request.cookies.get('refresh_time') user_id = get_cookie_info().get('user_id') # 这个个方法里存在单点登录状态 sso_code = get_cookie_info().get('sso_code') if is_none(auth_token) or is_none(refresh_time) or is_none(user_id): return BaseError.not_login() # 去redis中取 组装cookie时存的随机数 _redis = Redis() _sso_code = _redis.get_hget("app_sso_code", user_id) # 校验cookie解析出来的随机数 和存在redis中的随机数是否一致 if not is_none(_sso_code) and not is_none(sso_code) and sso_code != _sso_code: logger.info("账号在其他设备登陆了%s"% user_id) return BaseError.not_local_login() # 解密auth_token中的sign sign = aes_decrypt(auth_token) # 利用user_id + '#$%' + redis中随机数 + '#$%' + md5加密后的字符串 组装_sign _sign = hashlib.sha1(AUTH_COOKIE_KEY + user_id + refresh_time + sso_code).hexdigest() if sign == _sign: return f(*args, **kw) else: return BaseError.not_login()
def business_exception_log(e): if not is_none(request.trace_id) and not is_none(request.full_path): logger.error( 'BusinessException, code: %s, msg: %s trace_id: %s request path: %s' % (e.code, e.msg, request.trace_id, request.full_path)) else: logger.error('BusinessException, code: %s, msg: %s' % (e.code, e.msg))
def url_add_business_param(self, params): # 如果存在需要整个项目传的参数,则增加进params中 if not is_none(self.base_prj.params): for _service_key in self.base_prj.params: params[_service_key] =self.base_prj.params.get(_service_key) # 如果存在需要整个接口传的参数,则增加进params中 if not is_none(self.baseParams): for _key in self.baseParams: params[_key] = self.baseParams.get(_key) self.url = self.url + '¶ms=' + urllib.parse.quote_plus(json.dumps(params))
def create_auth_cookie(response, login_data): # 进场获取缓存cookie中的信息 auth_token = request.cookies.get('auth_token') refresh_time = request.cookies.get( 'refresh_time') # refresh_time = 1482222171524 cookie_info = request.cookies.get('cookie_info') # 设置cookie过期时间点, time.time() + 60 表示一分钟后 outdate = time.time() + 60 * 60 * 24 * 30 # 记录登录态三天 _redis = Redis() # login 如果是登录操作,cookie中所有信息重新生成 if not is_none(login_data) and not is_none(login_data.get('user_id')): user_id = login_data.get('user_id') sso_code = "vJjPtawUC8" # 如果当前版本不设置单点登录,则使用固定随机码 if get_version() in SSO_VERSION: # 如果版本设置单点登录,随机生成10位随机数,当做单机唯一登录码,存在redis中方便对比 # 只要不清除登录态,单点登录则不会触发 sso_code = get_randoms(10) _redis.set_hset("app_sso_code", user_id, sso_code) # 产生新的refresh_time 和新的auth_token refresh_time = str(int(round(time.time() * 1000))) sign = get_hashlib(AUTH_COOKIE_KEY + user_id + refresh_time + sso_code) auth_token = aes_encrypt(sign) login_data['sso_code'] = sso_code cookie_info = aes_encrypt(json.dumps(login_data)) # not login 如果不是登录操作,并且cookie中auth_token和refresh_time存在 if not is_none(auth_token) and not is_none(refresh_time): now_time = int(round(time.time() * 1000)) differ_minuts = (now_time - int(refresh_time)) / (60 * 1000) if differ_minuts >= 30 and is_none(login_data): user_id = get_cookie_info().get('user_id') if not is_none(user_id): refresh_time = str(int(round(time.time() * 1000))) sso_code = _redis.get_hget("app_sso_code", user_id) # 获取单点登录码 sign = get_hashlib(AUTH_COOKIE_KEY + user_id + refresh_time + sso_code) auth_token = aes_encrypt(sign) if not is_none(auth_token) and not is_none(refresh_time) and not is_none( cookie_info): response.set_cookie('auth_token', value=auth_token, domain='.mofanghr.com', expires=outdate, secure=True, httponly=True, samesite='Lax') response.set_cookie('refresh_time', value=str(refresh_time), domain='.mofanghr.com', expires=outdate) response.set_cookie('cookie_info', value=cookie_info, domain='.mofanghr.com', expires=outdate) return response
def url_add_business_param(self, params, url): # 如果存在需要整个项目传的参数,则增加进params中,例如 整个user服务需要加个参数 || {"source":"python"} if not is_none(self.base_prj.server_params): for _service_key, _service_value in self.base_prj.server_params.items( ): params[_service_key] = _service_value # 如果存在需要整个接口传的参数,则增加进params中 if not is_none(self.baseParams): for _key, _value in self.baseParams.items(): params[_key] = _value url = url + '¶ms=' + urllib.parse.quote_plus(json.dumps(params)) return url
def url_add_common_param(self): self.url = self.url + '?traceID=' + get_trace_id( ) + '&callSystemID=' + str(CALL_SYSTEM_ID) if not is_none(self.base_prj.common_params): for key, value in self.base_prj.common_params.items(): self.url = self.url + "&" + str(key) + "=" + str(value)
def system_exception(msg='后台系统异常'): if not is_none(request.trace_id): logger.error('request fail trace id is:' + str(request.trace_id)) logger.error(traceback.format_exc()) return BaseError.self_error(code=REQUEST_FAIL, msg=msg)
def request_fail(func=BaseError.system_exception): if not is_none(request.trace_id): logger.error('request fail trace id is:' + str(request.trace_id)) logger.error(traceback.format_exc()) return func()