def upd_token_exp(req_token, expt=None): """ 更新token过期时间 :param req_token: :param expt: 过期时间(秒) :return: """ r = RedisCtrl() user_info = r.get_one(REDIS_KEY_PRE_TOKEN + req_token) if user_info: if not expt: # 3小时 expt = 60 * 3600 * 3 r.set_one(REDIS_KEY_PRE_TOKEN + req_token, user_info, expt=expt)
def log_out(req): """ 登出 :param req: :return: """ ret = ResModel() token = req.META.get('HTTP_TOKEN') if token: # 获取redis缓存数据 r = RedisCtrl() r.del_one(REDIS_KEY_PRE_TOKEN + token) ret.code = ret.ResCode.succ ret.msg = "已退出登录" return JsonResponse(ret.to_dic())
def check_token(req_token): """ 校验token :param req_token: :return: """ user_info = {} ret_info = None if not req_token: ret_info = "请登录后访问" return ret_info, user_info r = RedisCtrl() user_info = r.get_one(REDIS_KEY_PRE_TOKEN + req_token) if user_info: user_info = loads(user_info) else: ret_info = "无效的token" return ret_info, user_info
def create_token(user_info: dict, expt=None): """ 生成token :param user_info: 必须为json字典,尽量简短 :param expt: 过期时间(秒) :return: """ if user_info.get("id"): r = RedisCtrl() token = str(uuid1()).replace('-', '') if not expt: # 3小时 expt = 60 * 3600 * 3 elif expt == -1: expt = None r.set_one(REDIS_KEY_PRE_TOKEN + token, dumps(user_info), expt=expt) return token else: raise ParamsVerifyError("生成用户token需有`id`作为必填key")
def vcode_sid(req): """ 验证码-获取sid 生成sid及验证码字符串,有效期10分钟 :param req: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) r = RedisCtrl() ret.data = str(uuid1()).replace("-", "").lower() r.set_one(REDIS_KEY_PRE_SID + ret.data, ValidCodeImg.getRandomStr(5), expt=60 * 10) ret.msg = '' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def sid_pic(req, sid): """ 验证码-根据sid生成图片 :param req: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: # 正常情况下get_sid和本函数是无间隔顺序调用的,所以不会出现redis中不存在的情况,不必友好提示 return JsonResponse(ret.to_dic()) # 生成验证码图片. i = ValidCodeImg(code_count=5, img_format='png') img_data, valid_str = i.getValidCodeImg(vcode_str=verify_code) ret.data = img_data.decode('utf8') ret.msg = '' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def email_reset_email(req, sid, vcode): """ 发送email验证码-更换/添加email :param req: :param sid: :param vcode: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) # 中间件校验token后赋值USER_ID user_id = req.META.get("USER_ID") if not user_id: ret.msg = "用户信息不存在" return JsonResponse(ret.to_dic()) email = req.POST.get("email") if not email: ret.msg = "请输入新EMAIL" return JsonResponse(ret.to_dic()) # 校验 r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) if verify_code.upper() != vcode.upper(): ret.msg = '验证码错误' # 记录错误次数,多次失败则需重新请求sid err_cnt = r.get_one(REDIS_KEY_PRE_SIDERR + sid) if not err_cnt: err_cnt = 1 r.set_one(REDIS_KEY_PRE_SIDERR + sid, str(err_cnt), expt=60 * 5) else: err_cnt = int(err_cnt) + 1 r.set_one(REDIS_KEY_PRE_SIDERR + sid, str(err_cnt), expt=60 * 5) if int(err_cnt) >= 10: # 尝试次数大于10次,则需重新请求sid r.del_one(REDIS_KEY_PRE_SID + sid) r.del_one(REDIS_KEY_PRE_SIDERR + sid) return JsonResponse(ret.to_dic()) # 查询用户信息 with connection() as con: user_rs = con.execute_sql( "select {table1_id} from {table1} where {table1_id}=%(uid)s". format(**SQL_DIC_USER), {"uid": user_id}) if not user_rs: ret.msg = "用户信息不存在" return JsonResponse(ret.to_dic()) # 新email重复性校验 user_rs2 = con.execute_sql( "select {table1_id} from {table1} where {table1_email}=%(email)s". format(**SQL_DIC_USER), {"email": email}) if user_rs2: ret.msg = "该email已被使用" return JsonResponse(ret.to_dic()) # email验证码发送 email_code = "%06d" % randint(0, 999999) r.set_one(REDIS_KEY_PRE_EMAILCODE + email, email_code, expt=60 * 6) send_ret = email_send([email], EMAIL_MODPHONE_TITLE, EMAIL_MODPHONE_CONT % email_code) flog.debug(email + f"重置密码时发送email验证码err:{send_ret}") ret.msg = '已发送' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def sms_reset_phone(req, sid, vcode): """ 发送短信验证码-更换/添加手机号 :param req: :param sid: :param vcode: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) # 中间件校验token后赋值USER_ID user_id = req.META.get("USER_ID") if not user_id: ret.msg = "用户信息不存在" return JsonResponse(ret.to_dic()) phone = req.POST.get("phone") if not phone: ret.msg = "请输入新手机号" return JsonResponse(ret.to_dic()) # 校验 r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) if verify_code.upper() != vcode.upper(): ret.msg = '验证码错误' # 记录错误次数,多次失败则需重新请求sid err_cnt = r.get_one(REDIS_KEY_PRE_SIDERR + sid) if not err_cnt: err_cnt = 1 r.set_one(REDIS_KEY_PRE_SIDERR + sid, str(err_cnt), expt=60 * 5) else: err_cnt = int(err_cnt) + 1 r.set_one(REDIS_KEY_PRE_SIDERR + sid, str(err_cnt), expt=60 * 5) if int(err_cnt) >= 10: # 尝试次数大于10次,则需重新请求sid r.del_one(REDIS_KEY_PRE_SID + sid) r.del_one(REDIS_KEY_PRE_SIDERR + sid) return JsonResponse(ret.to_dic()) # 查询用户信息 with connection() as con: user_rs = con.execute_sql( "select {table1_id} from {table1} where {table1_id}=%(uid)s". format(**SQL_DIC_USER), {"uid": user_id}) if not user_rs: ret.msg = "用户信息不存在" return JsonResponse(ret.to_dic()) # 新手机号重复性校验 user_rs2 = con.execute_sql( "select {table1_id} from {table1} where {table1_phone}=%(phone)s". format(**SQL_DIC_USER), {"phone": phone}) if user_rs2: ret.msg = "该手机号已被使用" return JsonResponse(ret.to_dic()) # 短信验证码发送 sms_code = "%06d" % randint(0, 999999) r.set_one(REDIS_KEY_PRE_SMSCODE + phone, sms_code, expt=60 * 5) sms_ret = sms_send(phone, {"code": sms_code}, ALI_SMS_TMPL_RESET_PHONE, "修改手机号验证码") flog.debug(f"修改手机号验证码发送:{sms_ret}") ret.msg = '已发送' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def reset_pwd(req, code_way, sid): """ 重置密码 :param req: :param code_way: smscode.短信验证码;emailcode.email验证码 :param sid: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) # 中间件校验token后赋值USER_ID user_id = req.META.get("USER_ID") if not user_id: ret.msg = "用户信息不存在" return JsonResponse(ret.to_dic()) # 图形验证码or短信验证码 auth_code = req.POST.get('authCode', '').upper() new_pwd = req.POST.get('newPwd', '').upper() if not auth_code: ret.msg = '验证码不可空' return JsonResponse(ret.to_dic()) if not new_pwd: ret.msg = '新密码不可空' return JsonResponse(ret.to_dic()) # 获取redis缓存数据 r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) if code_way == 'emailcode': # 登录方式.emailcode.email验证码 user_code = r.get_one(REDIS_KEY_PRE_EMAILCODE + user_id) elif code_way == 'smscode': # 登录方式.smscode.短信验证码 user_code = r.get_one(REDIS_KEY_PRE_SMSCODE + user_id) else: # 其他code_way,反馈失败 return JsonResponse(ret.to_dic()) # 校验验证码 if not user_code: # 短信验证码不存在 ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) if user_code != auth_code: # 校验验证码 ret.msg = '验证码错误' # 记录错误次数,多次失败则需重新请求sid err_cnt = r.get_one(REDIS_KEY_PRE_CODEERR + user_id) if not err_cnt: err_cnt = 1 r.set_one(REDIS_KEY_PRE_CODEERR + user_id, str(err_cnt), expt=60 * 5) else: err_cnt = int(err_cnt) + 1 r.set_one(REDIS_KEY_PRE_CODEERR + user_id, str(err_cnt), expt=60 * 5) if int(err_cnt) >= 10: # 尝试次数大于10次,则需重新发送sms r.del_one(REDIS_KEY_PRE_SMSCODE + user_id) r.del_one(REDIS_KEY_PRE_EMAILCODE + user_id) r.del_one(REDIS_KEY_PRE_CODEERR + user_id) # 同一个验证码尝试次数过多 flog.warning(f"重置密码时[{user_id}]用户的验证码尝试次数过多") ret.msg = '验证码错误,请重新加载' return JsonResponse(ret.to_dic()) # 设置密码 p = PwdCtrl() salt = p.get_salt() pwd = p.create_md5(src_str=new_pwd, salt=salt) with connection() as con: con.execute_sql( """update {table1} set {table1_pwd}=%(pwd)s,{table1_salt}=%(salt)s ,{table1_utime}=%(ut)s where {table1_id}=%(uid)s""".format(**SQL_DIC_USER), { "pwd": pwd, "uid": user_id, "salt": salt, "ut": fmt_date() }) ret.msg = '已修改密码' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def email_reset_pwd(req, sid, vcode): """ 修改密码-发送email验证码 :param req: :param sid: :param vcode: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) # 中间件校验token后赋值USER_ID user_id = req.META.get("USER_ID") if not user_id: ret.msg = "用户信息不存在" return JsonResponse(ret.to_dic()) # 校验 r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) if verify_code.upper() != vcode.upper(): ret.msg = '验证码错误' # 记录错误次数,多次失败则需重新请求sid err_cnt = r.get_one(REDIS_KEY_PRE_SIDERR + sid) if not err_cnt: err_cnt = 1 r.set_one(REDIS_KEY_PRE_SIDERR + sid, str(err_cnt), expt=60 * 5) else: err_cnt = int(err_cnt) + 1 r.set_one(REDIS_KEY_PRE_SIDERR + sid, str(err_cnt), expt=60 * 5) if int(err_cnt) >= 10: # 尝试次数大于10次,则需重新请求sid r.del_one(REDIS_KEY_PRE_SID + sid) r.del_one(REDIS_KEY_PRE_SIDERR + sid) return JsonResponse(ret.to_dic()) # 查询用户信息 with connection() as con: user_rs = con.execute_sql( "select {table1_id}, {table1_email} from {table1} where {table1_id}=%(uid)s" .format(**SQL_DIC_USER), {"uid": user_id}) if user_rs and user_rs[0]: user_obj = user_rs[0] if not user_obj.email: ret.msg = "您未绑定email地址" return JsonResponse(ret.to_dic()) else: ret.msg = "用户信息不存在" return JsonResponse(ret.to_dic()) # email验证码发送 email_code = "%06d" % randint(0, 999999) r.set_one(REDIS_KEY_PRE_EMAILCODE + user_obj.id, email_code, expt=60 * 6) email_send([user_obj.email], EMAIL_MODPWD_TITLE, EMAIL_MODPWD_CONT % email_code) ret.msg = '已发送' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def modify_pwd(req): """ 修改密码 :param req: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) # 中间件校验token后赋值USER_ID user_id = req.META.get("USER_ID") if not user_id: return JsonResponse(ResModelToLogin().to_dic()) old_pwd = req.POST.get('oldPwd', '').upper() new_pwd = req.POST.get('newPwd', '').upper() if (not old_pwd) or (not new_pwd): ret.msg = "请求参数缺失" return JsonResponse(ret.to_dic()) # db前校验 r = RedisCtrl() if r.get_one(REDIS_KEY_PRE_PWDERR + user_id + "_ERR"): ret.msg = "原密码错误,请" + str( r.get_ex_time(REDIS_KEY_PRE_PWDERR + user_id + "_ERR")) + "秒后再尝试" return JsonResponse(ret.to_dic()) # 校验用户信息 with connection() as con: user_rs = con.execute_sql( """select {table1_pwd},{table1_salt} from {table1} where {table1_id}=%(uid)s""".format( **SQL_DIC_USER), {"uid": user_id}) if (not user_rs) or (not user_rs[0]): # 按理说不会走这个if的,若走了,肯定有问题,不必友好提示 return JsonResponse(ResModelToLogin().to_dic()) user_rs = user_rs[0] # 密码校验 p = PwdCtrl() if user_rs.pwdValue.upper() != p.create_md5(src_str=old_pwd, salt=user_rs.pwdSalt): # 密码校验不通过 ret.msg = '原密码错误' # 错误次数,5分钟内,不可大于等于10次 err_cnt = r.get_one(REDIS_KEY_PRE_PWDERR + user_id) if not err_cnt: err_cnt = 1 r.set_one(REDIS_KEY_PRE_PWDERR + user_id, str(err_cnt), expt=60 * 5) else: err_cnt = int(err_cnt) + 1 r.set_one(REDIS_KEY_PRE_PWDERR + user_id, str(err_cnt), expt=60 * 5) if int(err_cnt) >= 10: r.del_one(REDIS_KEY_PRE_PWDERR + user_id) # 同一个手机号验证码尝试次数过多 flog.warning(f"修改密码时ID[{user_id}]用户的原密码尝试次数过多") r.set_one(REDIS_KEY_PRE_PWDERR + user_id + "_ERR", "ERR", expt=60 * 5) ret.msg = '原密码错误,请重新加载' return JsonResponse(ret.to_dic()) # 修改 salt = p.get_salt() pwd = p.create_md5(new_pwd, salt=salt) with connection() as con: con.execute_sql( """update {table1} set {table1_pwd}=%(pwd)s,{table1_salt}=%(salt)s where {table1_id}=%(uid)s""".format(**SQL_DIC_USER), { "uid": user_id, "pwd": pwd, "salt": salt }) ret.msg = '已修改' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def log_in(req, code_way, sid): """ log_in :param req: :param code_way: smscode.短信验证码;piccode.图形验证码 :param sid: 验证码会话sid :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 ret.code = ret.ResCode.fail return JsonResponse(ret.to_dic()) # 获取redis缓存数据 r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) # 图形验证码or短信验证码 auth_code = req.POST.get('authCode', '').upper() # 用户账户,若为短信方式,则该字段为手机号;图形验证码的话,该字段可以是account、email、phone user_acc = req.POST.get('userAcc', '') # 密码为为md5加密的值 pwd = req.POST.get('pwd', '').upper() # 是否需校验密码 need_check_pwd = False if code_way == 'piccode': # 登录方式.piccode.图形验证码 # 校验验证码 if (not settings.DEBUG) and (verify_code.upper() != auth_code): # 是否为debug模式,非debug模式,需校验验证码 ret.msg = '验证码错误' return JsonResponse(ret.to_dic()) need_check_pwd = True elif code_way == 'smscode': # 登录方式.smscode.短信验证码 sms_code = r.get_one(REDIS_KEY_PRE_SMSCODE + user_acc) if not sms_code: # 短信验证码不存在 ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) if (not settings.DEBUG) and (sms_code != auth_code): # 是否为debug模式,非debug模式,需校验验证码 ret.msg = '短信验证码错误' # 记录错误次数,多次失败则需重新请求sid err_cnt = r.get_one(REDIS_KEY_PRE_CODEERR + user_acc) if not err_cnt: err_cnt = 1 r.set_one(REDIS_KEY_PRE_CODEERR + user_acc, str(err_cnt), expt=60 * 5) else: err_cnt = int(err_cnt) + 1 r.set_one(REDIS_KEY_PRE_CODEERR + user_acc, str(err_cnt), expt=60 * 5) if int(err_cnt) >= 10: # 尝试次数大于10次,则需重新发送sms r.del_one(REDIS_KEY_PRE_SMSCODE + user_acc) r.del_one(REDIS_KEY_PRE_CODEERR + user_acc) # 同一个手机号验证码尝试次数过多 flog.warning(f"短信验证码登录时[{user_acc}]用户的短信验证码尝试次数过多") ret.msg = '短信验证码错误,请重新加载' return JsonResponse(ret.to_dic()) else: # 其他code_way,反馈失败 return JsonResponse(ret.to_dic()) # 查询用户信息 with connection() as con: user_rs = con.execute_sql( """select {table1_id}, {table1_account}, {table1_uname}, {table1_pwd}, {table1_salt}, {table1_wx}, {table1_qq}, {table1_phone}, {table1_email} from {table1} where ( {table1_account}=%(user_acc)s or {table1_phone}=%(user_acc)s or {table1_email}=%(user_acc)s)""".format( **SQL_DIC_USER), {"user_acc": user_acc} ) if user_rs and user_rs[0]: user_obj = user_rs[0] # 获取用户角色 role_rs = con.execute_sql( """select a.{tabler_id} as id from {tabler} a, {table3} b where a.{tabler_id}=b.{table3_rid} and b.{table3_uid}=%(uid)s""".format(**{**SQL_DIC_ROLES, **SQL_DIC_USERROLE}), {"uid": user_obj.id}) roles = ','.join([i.id for i in role_rs]) else: # 需校验密码的话,提示语要隐晦一些 ret.msg = '用户名或密码错误' if need_check_pwd else '用户信息不存在' return JsonResponse(ret.to_dic()) if need_check_pwd: # 接下来校验account-pwd 或 phone-pwd 或 email-pwd db_pwd = user_obj.pwdValue or '' db_salt = user_obj.pwdSalt # 密码校验 p = PwdCtrl() if db_pwd.upper() != p.create_md5(src_str=pwd, salt=db_salt): # 密码校验不通过 ret.msg = '用户名或密码错误' return JsonResponse(ret.to_dic()) # 记录登录日志 add_visitor(get_ip(req), apps.get_app_config('app_dr').name, 'login', user_obj.id) # 组织可见的user_info user_info = {"id": user_obj.id, "username": user_obj.userName, "account": user_obj.account} # 生成登录token # redis中额外放入元素roles等;但是不必返回前端 user_info_redis = {**user_info} user_info_redis["roles"] = roles token = create_token(user_info_redis) ret.data = {"token": token, "referer": req.META.get("HTTP_REFERER"), "userInfo": user_info} ret.msg = f'欢迎{user_obj.userName}' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def sms_log_in(req, sid, vcode): """ 登录-短信验证码发送 短信验证码有效期5分钟 :param req: :param sid: :param vcode: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) phone = req.POST.get('phone', '') if not phone: ret.msg = '参数异常' return JsonResponse(ret.to_dic()) # 校验 r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) if verify_code.upper() != vcode.upper(): ret.msg = '验证码错误' # 记录错误次数,多次失败则需重新请求sid err_cnt = r.get_one(REDIS_KEY_PRE_SIDERR + sid) if not err_cnt: err_cnt = 1 r.set_one(REDIS_KEY_PRE_SIDERR + sid, str(err_cnt), expt=60 * 5) else: err_cnt = int(err_cnt) + 1 r.set_one(REDIS_KEY_PRE_SIDERR + sid, str(err_cnt), expt=60 * 5) if int(err_cnt) >= 10: # 尝试次数大于10次,则需重新请求sid r.del_one(REDIS_KEY_PRE_SID + sid) r.del_one(REDIS_KEY_PRE_SIDERR + sid) return JsonResponse(ret.to_dic()) # 校验用户是否存在 with connection() as con: user_rs = con.execute_sql( """select {table1_id}, {table1_uname}, {table1_pwd}, {table1_salt}, {table1_wx}, {table1_qq}, {table1_phone}, {table1_email} from {table1} where {table1_phone}=%(phone)s """.format(**SQL_DIC_USER), {"phone": phone} ) if (not user_rs) or (not user_rs[0]): ret.msg = '当前用户信息不存在' return JsonResponse(ret.to_dic()) # 短信验证码发送 sms_code = "%06d" % randint(0, 999999) r.set_one(REDIS_KEY_PRE_SMSCODE + phone, sms_code, expt=60 * 5) sms_ret = sms_send(phone, {"code": sms_code}, ALI_SMS_TMPL_COMMON_CODE, "登录验证码") flog.debug(f"登录验证码发送:{sms_ret}") ret.msg = '已发送' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def log_in_openid(req, yw_name, openid): """ 根据openid登录 1.查询redis是否存在该openid用户: 1.1.存在则直接return 1.2.不存在则查询db: a.获取用户信息存入redis后return b.无用户信息则return空,可走注册流程 :param req: :param yw_name: :param openid: :return: """ ret = ResModel() app_idsecret = MINI_PROGRAM_APP_CONF.get(yw_name) if not app_idsecret: ret.msg = '未配置的应用名称' return JsonResponse(ret.to_dic()) ret.msg = '' ret.code = ret.ResCode.succ app_id, app_secret = app_idsecret user_obj = None r = RedisCtrl() token = r.get_one(app_id + openid) if token: user_obj = r.get_one(token) else: with connection() as con: sql = """select a.{table1_id}, a.{table1_uname}, a.{table1_pwd}, a.{table1_salt}, a.{table1_wx}, a.{table1_qq}, a.{table1_phone}, a.{table1_email} from {table1} a, {tableo} b where a.{table1_id}=b.{tableo_uid} and b.{tableo_aid}=%(appid)s and b.{tableo_oid}=%(oid)s """.format(**{**SQL_DIC_USER, **SQL_DIC_USEROPENID}) user_rs = con.execute_sql(sql, {"appid": app_id, "oid": openid}) if user_rs and user_rs[0]: user_obj = user_rs[0] else: ret.msg = '用户信息不存在' if user_obj: # 记录登录日志 add_visitor(get_ip(req), apps.get_app_config('app_mf').name, 'login', user_obj.id) # 组织可见的user_info user_info = {"id": user_obj.id, "username": user_obj.userName} # 生成登录token # 存入缓存格式: token:user_info token_tmp = create_token(user_info, expt=-1) # 存入缓存格式: appid+openid:token r.set_one(app_id + openid, token_tmp) ret.data = {"token": token_tmp, "userInfo": user_info} else: ret.data = {} return JsonResponse(ret.to_dic())
def reset_phone_email(req, code_way, sid): """ 更换/添加手机号、email :param req: :param code_way: smscode.短信验证码;emailcode.email验证码 :param sid: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) # 中间件校验token后赋值USER_ID user_id = req.META.get("USER_ID") if not user_id: ret.msg = "用户信息不存在" return JsonResponse(ret.to_dic()) # 图形验证码or短信验证码 auth_code = req.POST.get('authCode', '').upper() # 新phone或者新email new_aim = req.POST.get('newAim', '') if not auth_code: ret.msg = '验证码不可空' return JsonResponse(ret.to_dic()) if not new_aim: ret.msg = '参数异常' return JsonResponse(ret.to_dic()) # 获取redis缓存数据 r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) if code_way == 'emailcode': # 登录方式.emailcode.email验证码 user_code = r.get_one(REDIS_KEY_PRE_EMAILCODE + new_aim) ret.msg = '该email验证码已过期' sub_sql = "{table1_email}=%(new)s,{table1_emailsucc}='" + DrUser.EMAIL_SUCC[ 1][0] + "'," elif code_way == 'smscode': # 登录方式.smscode.短信验证码 user_code = r.get_one(REDIS_KEY_PRE_SMSCODE + new_aim) ret.msg = '该手机号验证码已过期' sub_sql = "{table1_phone}=%(new)s," else: # 其他code_way,反馈失败 return JsonResponse(ret.to_dic()) # 校验验证码 if not user_code: # 验证码不存在 return JsonResponse(ret.to_dic()) if user_code != auth_code: # 校验验证码 ret.msg = '验证码错误' # 记录错误次数,多次失败则需重新请求sid err_cnt = r.get_one(REDIS_KEY_PRE_CODEERR + user_id) if not err_cnt: err_cnt = 1 r.set_one(REDIS_KEY_PRE_CODEERR + user_id, str(err_cnt), expt=60 * 5) else: err_cnt = int(err_cnt) + 1 r.set_one(REDIS_KEY_PRE_CODEERR + user_id, str(err_cnt), expt=60 * 5) if int(err_cnt) >= 10: # 尝试次数大于10次,则需重新发送sms r.del_one(REDIS_KEY_PRE_SMSCODE + user_id) r.del_one(REDIS_KEY_PRE_EMAILCODE + user_id) r.del_one(REDIS_KEY_PRE_CODEERR + user_id) # 同一个验证码尝试次数过多 flog.warning(f"[{user_id}]用户的{code_way}验证码尝试次数过多") ret.msg = '验证码错误,请重新加载' return JsonResponse(ret.to_dic()) # 设置 with connection() as con: con.execute_sql( "update {table1} set " + sub_sql + ",{table1_utime}=%(ut)s where {table1_id}=%(uid)s".format( **SQL_DIC_USER), { "new": new_aim, "uid": user_id, "ut": fmt_date() }) ret.msg = '已修改' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def save_blog(req, mod_type): """ 保存 :param req: :param mod_type: add/upd :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 ret.code = ret.ResCode.fail return JsonResponse(ret.to_dic()) # 入参的非空校验 post_data = req.POST post_dic = { 'title': post_data.get('title', ""), 'title_notes': post_data.get('titleNotes', ""), 'blog_type': post_data.get('blogType', ""), 'blog_tags': post_data.get('blogTags', ""), 'content': post_data.get('content', ""), } if "" in post_dic.values(): ret.msg = '缺失字段:' + list(post_dic.keys())[list( post_dic.values()).index("")] return JsonResponse(ret.to_dic()) # 可空的入参 post_dic['id'] = post_data.get('id', '') post_dic['read_level'] = int(post_data.get('rLevel', '-1')) img_url = post_data.get('bgUrl') if not img_url: post_dic['bg_url'] = "" else: if img_url.startswith("/static"): post_dic['bg_url'] = img_url else: post_dic['bg_url'] = '/%s' % img_url.replace("\\", "/") # 字段长度校验 for k, v in post_dic.items(): length_ = BlogContent._meta.get_field(k).max_length if length_ and length_ < len(v): ret.msg = '内容超长:' + BlogContent._meta.get_field(k).verbose_name return JsonResponse(ret.to_dic()) if not BlogType.objects.filter(type_id=post_dic["blog_type"]): ret.code = ret.ResCode.fail ret.msg = "类型不合法" return JsonResponse(ret.to_dic()) post_dic["upd_time"] = timezone.now() # 登录用户信息 token = req.META.get('HTTP_TOKEN') r = RedisCtrl() user_info = r.get_one(REDIS_KEY_PRE_TOKEN + token) if user_info: user_info = loads(user_info) else: # 冗余校验 ret = ResModelToLogin() return JsonResponse(ret.to_dic()) if mod_type == 'upd': # 修改 rs = BlogContent.objects.filter(id=post_dic['id']) if not rs: ret.code = ret.ResCode.fail ret.msg = "未查询到该记录" return JsonResponse(ret.to_dic()) post_dic["upd_account"] = user_info["account"] post_dic["upd_name"] = user_info["username"] rs.update(**post_dic) else: # 新增 # insert post_dic["id"] = str(uuid1()).replace('-', '') post_dic["add_time"] = post_dic["upd_time"] post_dic["auth_account"] = user_info["account"] post_dic["auth_name"] = user_info["username"] BlogContent.objects.create(**post_dic) ret.code = ret.ResCode.succ ret.msg = "已保存" return JsonResponse(ret.to_dic())
def get_list(req): """ 角色列表 :param req: :return: """ ret = ResPageModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 ret.code = ret.ResCode.fail return JsonResponse(ret.to_dic()) ret.page = req.GET.get('page', '1') ret.limit = req.GET.get('limit', PAGE_DEFAULT_LIMIT) order_field = hump2underline(req.GET.get('orderField', '')) order_type = req.GET.get('orderType', '') name = req.GET.get('name', '') rid = req.GET.get('id', '') # 查询用户角色,若为超管,则不限制visible条件 filter_visible = True token = req.META.get('HTTP_TOKEN') r = RedisCtrl() user_info = r.get_one(REDIS_KEY_PRE_TOKEN + token) if user_info: user_info = loads(user_info) if DrRoles.type_sa in user_info['roles'].split(","): # 超管,不需限制visible条件 filter_visible = False # 数据查询sql sql = """select {tabler_id}, {tabler_name}, {tabler_level}, {tabler_orderno}, {tabler_note}, {tabler_visible}, to_char({tabler_atime}, 'yyyy-mm-dd hh24:mi:ss') as {tabler_atime} from {tabler} a where 1=1 """ sql_count = """select count(1) as cnt from {tabler} a where 1=1 """ # 查询条件 par_dic = {} if filter_visible: sql += " and a.{tabler_visible}=%(visible)s" sql_count += " and a.{tabler_visible}=%(visible)s" par_dic['visible'] = '1' if name: sql += " and {tabler_name} like %(name)s" sql_count += " and {tabler_name} like %(name)s" par_dic['name'] = f"%{name}%" if rid: sql += " and {tabler_id} = %(rid)s" sql_count += " and {tabler_id} = %(rid)s" par_dic['rid'] = rid # 排序 if order_field: sql += f" order by {order_field} {order_type}" else: sql += " order by a.{tabler_orderno} asc " with connection() as con: rs = con.execute_sql(sql_count.format(**SQL_DIC_ROLES), par_dic) ret.rsCount = rs[0].cnt # dicorobj需为dict ret.data = con.execute_sql(sql.format(**SQL_DIC_ROLES), par_dic, dicorobj="dict", page=ret.page, limit=ret.limit) ret.code = ret.ResCode.succ ret.msg = "" return JsonResponse(ret.to_dic())