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 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 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 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(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())