def __check_sendVcode(self, account, vcode, scene="signUp"): """校验发送的验证码 @param account str: 邮箱或手机号 @param vcode str: 验证码 @param scene str: 校验场景 signUp-注册 bindLauth-绑定本地账号 forgot-忘记密码 """ if email_check(account) or phone_check(account): if vcode and len(vcode) == 6 and scene in ("signUp", "bindLauth", "forgot"): key = "passport:vcode:{}:{}".format(scene, account) return self.rc.get(key) == vcode return False
def signUp(self, account, vcode, password, repassword, register_ip): """注册接口,面向前端 参数: @param account str: 注册的账号,邮箱/手机号 @param vcode str: 使用手机或邮箱的验证码 @param password str: 密码 @param repassword str: 重复密码 @param register_ip str: 注册IP地址 流程: 1. 判断账号类型,仅支持邮箱、手机号两种本地账号。 2. 校验密码、验证码是否合格、正确。 3. 密码、验证码通过后,当为邮箱时,校验邮箱是否存在;当为手机时,校验手机是否存在。 4. 生成guid,注册并响应事务结果。 """ res = dict(msg=None, success=False) # NO.1 检查账号类型 if email_check(account): # 账号类型:邮箱 # NO.2 检查密码、验证码 if password and repassword and password == repassword and 6 <= len( password) <= 30: certificate = generate_password_hash(password) if vcode and len(vcode) == 6 and self.__check_sendEmailVcode( account, vcode, scene="signUp"): # NO.3 检查账号是否存在 if self.__check_hasEmail(account): res.update(msg="Email already exists") else: guid = gen_uniqueId() upts = self.__signUp_transacion( guid=guid, identifier=account, identity_type=2, certificate=certificate, verified=1, register_ip=register_ip) res.update(upts) else: res.update(msg="Invalid verification code") else: res.update( msg= "Invalid password: Inconsistent password or length failed twice" ) elif phone_check(account): # 账号类型:手机 res.update(msg="Not support phone number registration") else: # 账号类型:非法,拒绝 res.update(msg="Invalid account") logger.info(res) return res
def __check_hasPhone(self, phone, getUid=False): """检查是否存在手机账号,不检测账号状态""" if phone_check(phone): sql = "SELECT uid FROM user_auth WHERE identity_type=1 AND identifier=%s" try: data = self.db.get(sql, phone) except Exception, e: logger.warn(e, exc_info=True) else: logger.debug(data) if data and isinstance(data, dict): success = "uid" in data return data["uid"] if success and getUid else success
def signIn(self, account, password): """登录接口,面向前端 参数: @param account str: 注册时的账号,邮箱/手机号 @param password str: 密码 流程: 1. 判断账号类型,仅支持邮箱、手机号两种本地账号。 2. 校验账号(是否合法、启用状态等)。 3. 校验密码(是否合格、正确)。 """ res = dict(msg=None, success=False) # NO.1 检查账号类型 if email_check(account) or phone_check(account): # 账号类型:邮箱、手机 identity_type = 2 if email_check(account) else 1 # NO.2 检查账号 if password and 6 <= len(password) < 30: sql = "SELECT uid,certificate FROM user_auth WHERE identity_type={} AND identifier=%s AND status=1".format( identity_type) try: data = self.db.get(sql, account) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: if data and isinstance(data, dict): uid = data["uid"] certificate = data["certificate"] if check_password_hash(certificate, password): res.update(success=True, uid=uid, identity_type=identity_type) else: res.update(msg="Wrong password") else: res.update( msg= "Invalid account: does not exist or has been disabled" ) else: res.update(msg="Invalid password: length unqualified")
message=email_tpl % (email, scenemap[scene], vcode)) if result["success"]: try: g.redis.set(key, vcode) g.redis.expire(key, 300) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: res.update( msg="Sent verification code, valid for 300 seconds", success=True) else: res.update( msg="Mail delivery failed, please try again later") elif phone_check(account): res.update(msg="Not support phone number") else: res.update(msg="Invalid account") logger.debug(res) return jsonify(dfr(res)) @ApiBlueprint.route("/miscellaneous/_getDownTime") def misc_getDownTime(): """Vaptcha宕机模式接口""" return jsonify(vaptcha.getDownTime) @ApiBlueprint.route("/miscellaneous/feedback/", methods=["POST"]) def misc_feedback():
def bindLauth(self, uid, account, vcode, password): """绑定本地化账号,需要密码做校验或重置 参数: @param account str: 注册时的账号,邮箱/手机号 @param vcode str: 验证码 @param password str: 密码 流程: 1. 检查参数是否合法 2. 检查账号类型、验证码 3. 检查用户是否有本地化账号 3.1 无本地化账号时,需要password参数生成密码,并且插入数据; 3.2 有本地化账号时,需要校验password是否匹配,匹配后: 3.3 如果账号类型已经绑定,则修改,否则插入 """ res = dict(msg=None, success=False, show_realname_tip=False) # NO.1 if uid and len(uid) == 22 and account and vcode and len( vcode) == 6 and password and 6 <= len(password) <= 30: # NO.2 if email_check(account) or phone_check(account): if self.__check_sendVcode(account, vcode, "bindLauth"): # NO.3 user_its = self.__list_identity_type(uid) identity_type = 1 if phone_check(account) else 2 # `绑定邮箱或手机`函数 def bindEmailOrPhone(): res = dict(success=False) sql = "INSERT INTO user_auth (uid, identity_type, identifier, certificate, verified, status, ctime) VALUES (%s, %s, %s, %s, %s, %s, %s)" try: self.db.insert(sql, uid, identity_type, account, generate_password_hash(password), 1, 1, get_current_timestamp()) except IntegrityError: res.update(msg="Account already bind") except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: res.update(success=True) if res["success"] and identity_type == 1: # 只有第一次绑定手机成功时设置为实名用户 res.update(show_realname_tip=True) return res # 用户的所有账号类型中包含1或2即存在本地化账号 if 1 in user_its or 2 in user_its: # NO3.2 有本地化账号 if self.__checkUserPassword(uid, password): # NO3.3 if identity_type in user_its: # 修改邮箱或手机 sql = "UPDATE user_auth SET identifier=%s,mtime=%s WHERE identity_type=%s AND uid=%s" try: self.db.update(sql, account, get_current_timestamp(), identity_type, uid) except IntegrityError: res.update(msg="Account already bind") except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: res.update(success=True) else: # 绑定邮箱或手机 res.update(bindEmailOrPhone()) else: res.update(msg="Wrong password") else: # NO3.1 无本地化账号, 绑定邮箱或手机 res.update(bindEmailOrPhone())