新闻详情——注册与登录逻辑
注册后端逻辑
@passport_blue.route("/register",methods = ["POST"]) def register(): """ 注册功能实现 1.接收参数(手机号,手机验证码,密码) 2.校验参数 2.1校验参数是否齐全 2.2校验手机号是否合法 2.3检查短信验证码是否正确 读取redis中存储的验证码 检查是否读取到验证码 对比是否正确 3.建立模型类对象 密码加密问题 4.提交到数据库中 5.注册即登录 6.返回内容 :return: """ # 注册功能实现 # 1.接收参数(手机号,手机验证码,密码) res_dict = request.json #一步到位,不需要刚刚那么麻烦json.lodas(request.data) mobile = res_dict.get("mobile") #手机号 smscode = res_dict.get("smscode") #短信验证码 password = res_dict.get("password") #密码 # 2.校验参数 # 2.1校验参数是否齐全 if not all([mobile,smscode,password]): return jsonify(errno=RET.PARAMERR,errmsg="参数错误") # 2.2校验手机号是否合法 if not re.match("^1[3789][0-9]{9}$",mobile): return jsonify(errno=RET.PARAMERR,errmsg="手机号不合法") # 2.3检查短信验证码是否正确 # 读取redis中存储的验证码 try: sms_code_server = redis_store.get("sms_code:"+mobile) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR,errmsg="手机验证码读取失败") # 检查是否读取到验证码 if not sms_code_server: return jsonify(errno=RET.NODATA,errmsg="未读取到手机验证码") # 对比是否正确 if sms_code_server != smscode: return jsonify(errmo=RET.PARAMERR,errmsg="手机验证码错误") # 3.建立模型类对象 user = User() # 调用模型类 user.mobile = mobile # 用户手机号就用手机号 user.nick_name = mobile # 先用手机号代替昵称 user.last_login = datetime.datetime.now() # 设置最后一次登录时间,now代表当前 user.password= password # 在models设置加密 # 4.将模型数据同步到数据库 #提交要用到db连接对象,在前面先导包 try: db.session.add(user) #分为逻辑添加和真正添加,因为在数据库操作,添加一个try db.session.commit() except Exception as e: current_app.logger.error(e) db.session.rollback() #添加这个是因为,前面写一半断了,就用这行代码,回到没有保存之前的一个状态 return jsonify(errno=RET.DBERR,errmsg="保存注册数据失败") #在return返回信息 # 5.注册即登录 session["mobile"] = user.mobile #用户的信息是私密的,所以使用session session["id"] = user.id #session里面要存的数据分别是id,昵称,手机号 session["nick_name"] = user.nick_name # 6.返回内容 return jsonify(errno=RET.OK, errmsg='注册成功')
关于密码加密通常有三种方式:
- 方案一:在这个视图中,直接调用对应的密码加密的算法,加密密码存储到数据库
- 方案二:在这个视图中,封装一个加密的方法,加密密码存储到数据库
- 方案三:在模型类中新增一个属性叫做password,并加载setter和getter方法,调用setter方法,直接完成密码的加密存储
前两种方式会将加密方式暴露在视图中,所以这个项目中使用的密码加密方式是第三种,这种方法也是对python面向对象和程序设计时降低代码耦合度的较好体现。
我们需要去到info的models里去写入加密代码,在用户下方隔两层再写,写的时候,这里有一个快捷键props。
@property def password(self): return "you can't read" @password.setter def password(self, value): self.password_hash = generate_password_hash(value)
注册前端逻辑
因为index.html里面并没有写注册的相关函数,但在a标签有这么一个函数阻止了a标签跳转,肯定是在js里面做了手脚的
在index.html文件里连按两下shift,输入main找到js文件点进去
找到图片中的位置加入代码
// 发起登录请求 var params = { 'mobile':mobile, 'password':password }; $.ajax({ url:'/passport/login', type:'post', data:JSON.stringify(params), contentType:'application/json', headers:{'X-CSRFToken':getCookie('csrf_token')}, // 在请求头中带上csrf_token success:function (response) { if (response.errno == '0') { // 当你注册成功后刷新当前页面 location.reload(); } else { alert(response.errmsg); } } });
运行成功之后:
最后一个才是注册成功之后的,前面是没有加密的密码。
登录后台逻辑
注册成功开始写登录了,根据表来写接口
@passport_blue.route("/login",methods = ["POST"]) def login(): """ 实现登录功能 1.接受参数(手机号,密码) 2.校验参数 2.1校验参数是否齐全 2.2校验手机号 利用手机号从数据库中找到对应的用户信息 如果没有找到就没有该用户 2.3校验密码 注意加密位置,加密方式不会暴露给别人的,所以是在models里面加密的,肯定也是在里面校验 3.写入session数据 4.更新最后一次登陆时间 5.返回内容 :return: """ # 实现登录功能 # 1.接受参数(手机号,密码) res = request.json #一步到位,不需要刚刚那么麻烦json.lodas(request.data) mobile = res.get("mobile") password = res.get("passwprf") # 2.校验参数 # 2.1校验参数是否齐全 if not all([mobile,password]): return jsonify(errno=RET.PARAMERR,errmsg="缺少参数") # 2.2校验手机号 if not re.match("^1[3-9][0-9]{9}$",mobile): return jsonify(errno=RET.PARAMERR,errmsg="手机号不合法") # 利用手机号从数据库中找到对应的用户信息 #过滤器 #执行器 try: user = User.query.filter_by(mobile=mobile).first() #这两种方法都可以,看自己习惯哪一种 # User.query.filter(User.mobile==mobile).first() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="数据库查询失败") # 如果没有找到就没有该用户 if not user: return jsonify(errno=RET.NODATA, errmsg="没有找到该用户") # 2.3校验密码 if not user.check_password(password): return jsonify(errno=RET.PARAMERR, errmsg="用户或者密码错误") # 注意加密位置,加密方式不会暴露给别人的,所以是在models里面加密的,肯定也是在里面校验 # 3.入session数据 session["mobile"] = user.mobile session["id"] = user.id session["nick_name"] = user.nick_name # 4.更新最后一次登陆时间 user.last_login = datetime.datetime.now() try: db.session.commit() except Exception as e: current_app.logger.error(e) db.session.rollback() return jsonify(errno=RET.DATAERR, errmsg="数据库更新失败") # 5.返回内容 return jsonify(errno=RET.OK, errmsg="登陆成功")
密码怎么校验了,你不能把你的加密方式告诉别人,所以在models里面处理
在你的models里面,创建一个函数
我们在views里用user调用这个函数的时候,意味着把这个实例化对象传到self了,我们就可以用self.的形式来调用密码
但密码还是加密的,所以我们使用check_possword_push来校验
在check_ppossword_push()里面要填写两个参数,把刚刚写好的self.password_hash丢进去,还有一个明文密码,但是views里并没有传过一个内容,我们把用户填写的明文密码传过去
在回到models里,在self.possword_hash后面加上password,当然了,要用一个变量来接收的
写完这些后,它的一个结果是true或者false,那么就把这个内容return回去
登录前台逻辑
在index页面里,和注册一样,没有相关函数,阻止了a标签跳转,在js文件里进行操作
找到它的位置,把相关代码写进去
// 发起登录请求 var params = { 'mobile':mobile, 'password':password }; $.ajax({ url:'/passport/login', type:'post', data:JSON.stringify(params), contentType:'application/json', headers:{'X-CSRFToken':getCookie('csrf_token')}, // 在请求头中带上csrf_token success:function (response) { if (response.errno == '0') { // 登录成功后刷新当前界面 location.reload(); } else { alert(response.errmsg); } } });