说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/85934776

目录

一丶登录后端接口编写

二丶登录接口测试

三丶登录前端编写

四丶用户登录功能测试

五丶定义检查登录状态与用户退出接口

六丶效果图


一丶登录后端接口编写

1.获取参数

req_dict = request.get_json()
mobile = req_dict.get("mobile")
password = req_dict.get("password")

2.校验参数的完整性

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

3.校验手机号码格式

if not re.match(r"1[345789]\d{9}", mobile):
    return jsonify(errno=RET.PARAMERR, errmsg="手机号码格式错误")

4.将用户登录的错误次数以用户的IP作为标识,保存到redis数据库中,通过redis数据库来限制时间,如次数超过10分钟内错误登录超过5次

  • step1 获取用户IP地址
user_ip = request.remote_addr
  • step2 判断用户登录错误次数是否超出限制
try:
    access_nums = redis_store.get("access_nums_%s" % user_ip)
except Exception as e:
    current_app.logger.error(e)
else:
    if access_nums is not None and int(access_nums) >= constants.LOGIN_ERROR_MAX_TIMES:
        return jsonify(errno=RET.REQERR, errmsg="错误次数过多,请稍后重试")

5.从数据库中根据用户手机号查询对应的数据对象user

try:
    user = User.query.filter_by(mobile=mobile).first()
except Exception as e:
    current_app.logger.error(e)
    return jsonify(errno=RET.DBERR, errmsg="获取用户信息失败")

6.校验用户输入的手机号以及密码与数据库是否一致,将用户名(手机号)与密码放在一起进行校验,不管是密码错误还是用户名错误,返回的提示信息都为用户名或密码错误,不展示细节与前端上

  • step1 在models中定义一个校验密码的函数
def check_password(self, passwd):
    """
    检验用户输入密码与数据库中密码是否一致
    :param passwd: 用户输入的原始密码
    :return: 匹配正确返回True 否则 返回false
    """
    return check_password_hash(self.password_hash, passwd)
  • step2 回过头在passport中进行校验
if user is None or user.check_password(password) is False:
    return jsonify(errno=RET.DATAERR, errmsg="用户名或密码错误")

7.验证失败需要记录失败次数,保存到redis数据库中

  • step1 通过redis数据库python中的incr方法累积保存access_nums_ip到redis数据库中
redis_store.incr("access_nums_%s" % user_ip)
  • step2 设置access_nums_ip键的有效期
redis_store.expire("access_nums_%s" % user_ip, constants.LOGIN_ERROR_FORBID_TIME)
  • step3 抛出异常,并记录到日志中
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:
    current_app.logger.error(e)

8.如果用户名和密码验证成功,则将登录成功状态保存到session中,并返回正确响应

session["name"] = user.name
session["mobile"] = user.mobile
session["user_id"] = user.id

return jsonify(errno=RET.OK, errmsg="登录成功")

二丶登录接口测试

1.在ihome/init中注释CSRF验证,运行程序

python manage.py runserver

2.Postman测试工具中添加127.0.0.1:5000/api/v1.0/sessions登录接口路由

3.查看之前我们测试注册接口时注册的账号密码

4.在Postman工具中构造Body体JSON数据

  • step1 构造错误数据,输入错误密码,查看提示

  • step2 输入错误账号

  • step3 多次错误登录

查看数据库中保存的登录错误次数

  • step4 输入正确账号和密码

三丶登录前端编写

1.前端登录HTML代码(不展示)

2.前端登录JS代码(不展示)

3.在login.js中在submit提交回调函数中进行如下编写

// 将表单的数据存到对象data中
var data = {
    mobile:mobile,
    password:passwd
};
// 将data数据转换成json字符串
var jsonData = JSON.stringify(data);
$.ajax({
    url:"/api/v1.0/sessions",
    type:"post",
    data:jsonData,
    contentType:"application/json",
    dataType:"json",
    headers:{
        "X-CSRFToken":getCookie("csrf_token")
    },
    success:function (data) {
        if(data.errno == "0"){
            // 则代表登录成功,跳转到主页
            location.href = "/";
        }
        else {
            // 登录不成功则在页面中显示错误信息
            $("#password-err span").html(data.errmsg);
            $("#password-err").show();
        }
    }
})

4.在js构建一个getCookie的方法来获取前端名为csrf_token的cookie的值

function getCookie(name) {
    var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
    return r ? r[1] : undefined;
}

5.将获取的cookie的值,放在请求头中的X-CSRFToken键中,方便后端进行csrf验证(需将ihome/init中的CSRF验证开启)

headers:{
          "X-CSRFToken":getCookie("csrf_token")
        },

四丶用户登录功能测试

1.运行程序后,在http://127.0.0.1:5000/login.html 上进行测试

2.输入错误的账号或密码

3.输入正确的用户名和密码,跳转到主页(这里还没有完善,在登录成功后右上角不再显示登录与注册,而是显示登录时的用户名 )

五丶定义检查登录状态与用户退出接口

1.检查登录状态

@api.route("/session", methods=["GET"])
def check_login():
    """
    检查登录状态
    :return:
    """
    # 从注册和登录成功时保存到session数据中获取name的值
    name = session.get("name")
    # name不为空,则返回ok,并将name以字典形式传给前端,为空则返回对应错误信息
    if name is not None:
        return jsonify(errno=RET.OK, errmsg="true", data={"name":name})
    else:
        return jsonify(errno=RET.SESSIONERR, errmsg="false")

2.用户退出(清除session数据)

@api.route("/session", methods=["DELETE"])
def logout():
    """
    用户退出 清除session数据
    :return:
    """
    session.clear()
    return jsonify(errno=RET.OK, errmsg="OK")

3.登录成功时,跳转到主页,那么在index.js中进行编写,因为是当页面加载完时需要显示出用户名,所以在$(document).ready下进行编写即可

$.get("/api/v1.0/session", function (resp) {
        if (resp.errno == "0"){
            $(".top-bar>.user-info>.user-name").html(resp.data.name);
            $(".top-bar>.user-info").show();
        }
        else {
            $(".top-bar>.register-login").show();
        }
    }"json");

4.当登录成功后,主页右上角显示用户名(手机号),点击用户名进入后,在个人主页,点击退出再回到主页,此时主页右上角显示登录和注册,那么需要在my.js中进行如下代码编写

function logout() {
    $.ajax({
        url:"/api/v1.0/session",
        type:"delete",
        headers:{
            "X-CSRFToken":getCookie("csrf_token")
        },
        dataType:"json",
        success:function (resp) {
            if (resp.errno == "0"){
                location.href = "/"
            }
        }
    })
}

六丶效果图

Flask项目之手机端租房网站的实战开发(七)的更多相关文章

  1. Flask项目之手机端租房网站的实战开发(三)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  2. Flask项目之手机端租房网站的实战开发(一)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 一丶项目介绍 产品:关于手机移动端的租房网站 角色:在这个产品中用户包括房东与房客 功能:房东可以在这个平台发布自己的房屋,房客可 ...

  3. Flask项目之手机端租房网站的实战开发(二)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  4. Flask项目之手机端租房网站的实战开发(十四)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  5. Flask项目之手机端租房网站的实战开发(六)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  6. Flask项目之手机端租房网站的实战开发(十一)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  7. Flask项目之手机端租房网站的实战开发(十)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  8. Flask项目之手机端租房网站的实战开发(九)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  9. Flask项目之手机端租房网站的实战开发(八)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  10. Flask项目之手机端租房网站的实战开发(四)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

随机推荐

  1. Ubuntu系统下的多路径软件 DM Multipath 配置。

    Ubuntu系统下的多路径软件是操作系统自带的 DM Multipath工具.------------------------------------------------------------- ...

  2. 昼猫笔记 JavaScript -- 作用域技巧!!

    简单理解 var zm = function (x) { var code = 'bb' return code }; 学过js的老哥们都知道,当这样简单的一个函数进入浏览器,浏览器开始解释代码,会将 ...

  3. 10G安装DataGuard

    最后更新时间:2013年8月4日,星期日 ★ oracle 10G安装环境 数据库软件安装环境不详细描述,网上到处有这方面资料,下面只简单描述下. 也可参考官方文档: http://docs.orac ...

  4. 学习推荐《Python神经网络编程》中文版PDF+英文版PDF+源代码

    推荐非常适合入门神经网络编程的一本书<Python神经网络编程>,主要是三部分: 介绍神经网络的基本原理和知识:用Python写一个神经网络训练识别手写数字:对识别手写数字的程序的一些优化 ...

  5. Yeslab华为安全HCIE七门之-防火墙UTM技术(5篇)

    课程目录:     华为安全HCIE-第四门-防火墙UTM技术(5篇)\1_内容安全_内容过滤.avi 华为安全HCIE-第四门-防火墙UTM技术(5篇)\2_内容安全-url过滤.avi 华为安全H ...

  6. route---设置Linux内核中的网络路由表

    route命令用来显示并设置Linux内核中的网络路由表,route命令设置的路由主要是静态路由.要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现. 在L ...

  7. UI_搭建MVC

    新建RootViewController 继承于 UIViewController 新建RootView 继承于 UIView AppDelegate.m 中引入 #import "Root ...

  8. 洛谷P1439 最长公共子序列(LCS问题)

    题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...

  9. GridDataView实现 点击任意一格可以修改

    直接上代码好了 private void dgv1Member_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { string ...

  10. terminfo 数据库?

    什么是 terminfo 数据库? UNIX 系统上的 terminfo 数据库用于定义终端和打印机的属性及功能,包括各设备(例如,终端和打印机)的行数和列数以及要发送至该设备的文本的属性.UNIX ...