该项目为前后端分离的项目,前端完成了相关的操作,在登录的过程中,使用到了登录页面和注册页面,分别是两个不同的HTML,点击网页中的登录或注册,可以触发程序中的passport,传入相关的参数,在程序中进行了相关的验证,经过验证后确定是否可以登录和注册
在获得内容之后依次进行以下判断,然后进入登录,
passport:验证登录逻辑:
使用到的资源:Redis数据库 数据库
进行相关的判断
通过获取HTML端的request,从里面抽取出json字典,对字典的数据进行相关的处理和判断
相关代码:
from . import api
from flask import request, jsonify, session
from lghome.response_code import RET
from lghome import redis_store
from lghome.models import User
import re
import logging
from lghome import db
from sqlalchemy.exc import IntegrityError
from lghome import constants
import time
@api.route("/users", methods=["POST"])
def register():
"""
注册
:param: 手机号 短信验证码 密码 确认密码
:return: json
"""
# 接收参数
request_dict = request.get_json()
#print(time.strftime("%Y--%m--%d %H:%M:%S",time.localtime(time.time())),' '*5,1)
print(request_dict)
mobile = request_dict.get("mobile")
sms_code = request_dict.get("sms_code")
password = request_dict.get("password")
password2 = request_dict.get("password2")
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 2)
# 验证
if not all([mobile, sms_code, password, password2]):
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 3)
return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
# 判断手机号格式
if not re.match(r'1[345678]\d{9}', mobile):
#print(time.strftime("%Y--%m--%d %H:%M:%S",time.localtime(time.time())),' '*5,4)
return jsonify(errno=RET.PARAMERR, errmsg='手机号格式错误')
if password != password2:
#print(time.strftime("%Y--%m--%d %H:%M:%S",time.localtime(time.time())),' '*5,5)
return jsonify(errno=RET.PARAMERR, errmsg='两次密码不一致')
# 业务逻辑
# 从redis取短信验证码
try:
#print(time.strftime("%Y--%m--%d %H:%M:%S",time.localtime(time.time())),' '*5,6)
real_sms_code = redis_store.get("sms_code_%s" % mobile)
except Exception as e:
logging.error(e)
return jsonify(errno=RET.DBERR, errmsg='读取短信验证码异常')
# 判断短信验证码是否过期
if real_sms_code is None:
return jsonify(errno=RET.NODATA, errmsg='短信验证码失效')
# 删除redis中的短信验证码
try:
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 7)
redis_store.delete("sms_code_%s" % mobile)
except Exception as e:
logging.error(e)
# 判断用户填写的验证码的正确性
real_sms_code = real_sms_code.decode()
if real_sms_code != sms_code:
return jsonify(errno=RET.DATAERR, errmsg='短信验证码错误')
# 判断手机号是否存在
# try:
# user = User.query.filter_by(mobile=mobile).first()
# except Exception as e:
# logging.error(e)
# else:
# if user is not None:
# # 表示手机号已经被注册过
# return jsonify(errno=RET.DATAEXIST, errmsg='手机号已经存在')
# 保存数据
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 8)
user = User(name=mobile, mobile=mobile)
# print(user.password)
user.password = password
# user.generate_pwd_hash(password)
# print(user.password_hash)
# User(name=mobile, mobile=mobile, password_hash='加密之后的密码')
try:
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 9)
db.session.add(user)
db.session.commit()
except IntegrityError as e:
db.session.rollback()
logging.error(e)
return jsonify(errno=RET.DATAEXIST, errmsg='手机号已经存在')
except Exception as e:
# 回滚
db.session.rollback()
logging.error(e)
return jsonify(errno=RET.DBERR, errmsg='插入数据库异常')
# pwd = user.password_hash(password)
# user.password_hash = pwd
# , password_hash=password 密码需要加密 csdn 明文 MySQL 居然 xxxx
# md5 f13d4eaa933978379554abb0ddbe617e juran
# 123456 f13d4exxxx978379xxx0ddbxxe617e
# md5 + salt(盐)
# sha1 sha256
# 保存登录状态到session中
session["name"] = mobile
session["mobile"] = mobile
session["user_id"] = user.id
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 10)
# 返回结果
return jsonify(errno=RET.OK, errmsg='注册成功')
@api.route("/sessions", methods=["POST"])
def login():
"""
用户登录
:param: 手机号,密码
:return: json
"""
# 接收参数
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 101)
#time.sleep(3)
request_dict = request.get_json()
print(request_dict)
mobile = request_dict.get('mobile')
password = request_dict.get('password')
# 校验参数
if not all([mobile, password]):
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 102)
return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
# 判断手机号格式
if not re.match(r'1[345678]\d{9}', mobile):
# print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 103)
return jsonify(errno=RET.PARAMERR, errmsg='手机号格式错误')
# 业务逻辑处理
# 判断错误次数是否超过限制,如果超过限制直接返回
# redis 用户IP地址:次数
user_ip = request.remote_addr
try:
# bytes
# print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 104)
#time.sleep(3)
access_nums = redis_store.get("access_nums_%s" % user_ip)
except Exception as e:
logging.error(e)
else:
if access_nums is not None and int(access_nums) >= constants.LOGIN_ERROR_MAX_TIMES:
return jsonify(errno=RET.REQERR, errmsg='错误次数太多,请稍后重试')
# 从数据库中查询手机号是否存在
try:
user = User.query.filter_by(mobile=mobile).first()
except Exception as e:
logging.error(e)
# 查询时候的异常
return jsonify(errno=RET.DBERR, errmsg='获取用户信息失败')
# 验证密码
# pwd = check_password_hash(user.password_hash, password)
# if pwd != user.password_hash:
if user is None or not user.check_pwd_hash(password):
try:
redis_store.incr("access_nums_%s" % user_ip)
redis_store.expire("access_nums_%s" % user_ip, constants.LOGIN_ERROR_FORBID_TIME)
except Exception as e:
logging.error(e)
return jsonify(errno=RET.DATAERR, errmsg='账号密码不匹配')
# 保存登录状态
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 105)
#time.sleep(3)
session['name'] = user.name
session['mobile'] = user.mobile
session['user_id'] = user.id
#print(time.strftime("%Y--%m--%d %H:%M:%S", time.localtime(time.time())), ' ' * 5, 106)
# 返回
return jsonify(errno=RET.OK, errmsg='登录成功')