我爱吃北京

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  做过网站开发的朋友应该知道,在保存客户信息的时候,是不能明文保存用户密码等重要信息的,都是通过加密后再保存到数据库的。笔者在用flask框架写一个注册页面时,当然也意识到这个问题了。这里关于flask环境搭建就不细说了,直接码关键的部分代码了

  当用户传进来的数据到相应的api时,我们通过框架获取到用户传过来明文用户名等数据:

@api.route('/users', methods=["POST"]) 
def register():
  """注册"""
  # 获取参数 手机号、短信验证码、密码、确认密码 请求体(json格式)
  req_dict = request.get_json()
  mobile = req_dict.get("mobile")
  password = req_dict.get("password")
  password2 = req_dict.get("password2")

  # 校验参数完整性

  if not all([mobile, sms_code, password, password2]):
    return jsonify(errcode=RET.PARAMERR, errmsg="参数不完整")

  # 验证手机号格式
  if not re.match(r"1[3456789]\d{9}", mobile):
  # 表示格式错误
    return jsonify(errcode=RET.PARAMERR, errmsg="手机号格式错误")

  # 判断密码一致
  if password != password2:
    return jsonify(errcode=RET.PARAMERR, errmsg="两次密码不一致")

  # 将用户数据保存到数据库中

  在保存前,要将密码先处理一下,这里用到了Flask框架自带的模块

  from werkzeug.security import generate_password_hash

  password_hash = generate_password_hash(password)
  user = User(
      name=mobile,
      password_hash=password_hash,
      mobile=mobile
      )

  这里看起来是不是也很正常,但是笔者希望是用user.password = password来设置属性

  所以这里用将类先做些修改 

class User(db.Model):
  """用户"""

  __tablename__ = "ih_user_profile"

  id = db.Column(db.Integer, primary_key=True) # 用户编号
  name = db.Column(db.String(32), unique=True, nullable=False) # 用户暱称
  password_hash = db.Column(db.String(128), nullable=False) # 加密的密码  
  mobile = db.Column(db.String(11), unique=True, nullable=False) # 手机号
  real_name = db.Column(db.String(32)) # 真实姓名
  avatar_url = db.Column(db.String(128)) # 用户头像路径
  

  def check_password(self, origin_password):
    """检验用户的密码是否正确,是框架自身提供的方法
    : param origin_password: 用户登录时输入的原始密码
    """
    return security.check_password_hash(self.password_hash, origin_password)

  # property装饰器将方法变成属性password
  @property
  def password(self):
    """
    对应额外添加的属性password的读取行为
    :return:
    """
    # 在我们这个应用场景中,读取密码没有实际意义
    # 所以对于password属性的读取行为的函数不再实现
    # 通常以抛出AttributeError的方式来作为函数代码
    raise AttributeError("不支持读取操作")

  @password.setter
  def password(self, origin_password):
    """
    对应额外添加的属性password的设置行为
    : params origin_password: 在进行属性设置的时候,要设置的值 # user.password = origin_password
    :return:
    """
    self.password_hash = security.generate_password_hash(origin_password)

通过property装饰后,再次定义类属性时,就可以直接来写:

  user = User(
      name=mobile,
      password_hash="",
      mobile=mobile
      )

  user.password = password

看到这里,应该有了一个认识,当修改类属性时,需要对传入的数据进行处理,而不是直接赋值时,就可以使用描述符!

posted on 2018-02-27 12:41  我爱吃北京  阅读(298)  评论(0编辑  收藏  举报