Пример #1
0
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)
Пример #2
0
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())
Пример #3
0
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
Пример #4
0
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")
Пример #5
0
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())
Пример #6
0
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())
Пример #7
0
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())
Пример #8
0
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())
Пример #9
0
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())
Пример #10
0
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())
Пример #11
0
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())
Пример #12
0
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())
Пример #13
0
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())
Пример #14
0
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())
Пример #15
0
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())
Пример #16
0
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())
Пример #17
0
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())