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

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

目录

一丶在项目中添加静态资源文件

二丶关于csrf防护机制

三丶用户注册模块(图片验证码以及短信验证码)

四丶测试后端verify_code接口是否正确


一丶在项目中添加静态资源文件

1.将静态资源文件拷贝到项目static目录下

2.在终端上运行项目python manage.py runserver

3.在浏览器中输入http://127.0.0.1:5000/static/html/index.html 访问前端主页,如下图

4.当在不使用nginx服务器给用户提供静态资源,而是以flask来提供,当用户在浏览器中输入/static/html/index.html就会显得不友好,正常来说访问主页只需要输入ip地址或者是域名加端口号就可以了,那么就需要我们专门写个视图函数来提供有好的链接地址,把地址前缀给去掉

5.创建一个蓝图,专门负责提供静态文件的

  • step1 在ihome目录下创建一个web_html.py文件
  • step2 创建蓝图html
html = Blueprint("web_html", __name__)
  • step3 在utils目录下创建一个__init__.py文件,使这个目录变成python的包,然后在这个utils包中创建commons.py文件,作为通用工具,在里面定义一个正则转换器

  • step4 在ihome/init文件中,在创建app对象时候,将ReConverter对象添加到app中

  • step5 回到commons.py文件中,定义视图函数get_html

  • step6 在ihome/init中进入此蓝图注册

  • step7 启动项目
python manage.py runserver
  • step8 清除网页缓存数据

二丶关于csrf防护机制

1.csrf验证机制:从cookie中获取一个csrf_token的值,再从请求体中获取一个csrf_token的值,如果这两个值相同,则检
验通过,可以进入视图函数中执行,如果两个值不同,则检验失败,会想前端返回状态码404的错,之前在ihome/init中设置的csrf只是负责验证,并不负责cookie与请求体中的csrf_token的值从哪里来

    # 为flask补充csrf防护
    CSRFProtect(app)

2.分析:前后端不分离时跟django一样直接在模板中进行设置csrf,而我们这个项目使用的是前后端分离,没有模板,对于cookie我们可以提前进行设置csrf_token,然后对于请求体中的cookie而言,当 发送POST请求时,就将那时候的请求体数据中设置csrf_token这样就能csrf防护了

3.设置cookie中的csrf_token

  • step1 为web_html.py中导入csrf包
from flask_wtf import csrf
  • step2 创建一个csrf_token的值
csrf_token = csrf.generate_csrf()
  • step3 导入make_response,将返回的静态文件方法的值构建成响应对象
resp = make_response(current_app.send_static_file(html_file_name))
  • step4 设置cookie的值,有效期为临时会话
resp.set_cookie("csrf_token", csrf_token)
  • step5 重新启动程序,刷新网页,查看我们设置的cookie

三丶用户注册模块(图片验证码以及短信验证码)

1.图片验证码使用流程

  • step1 分析流程:

第一步,需要前端像后端发起一个获取图片验证码的请求,对于后端来说就需要去生成一个随机的验证码图片;第二步将生成的验证码图片返回给前端;第三步验证图片验证码的准确性,如果正确,才能发起获取短信验证码的请求

  • step2 具体细节

在发起获取短信验证码请求的时候将携带填写的图片验证码与后端生成的图片验证码进行校验,因此后端在生成图片验证码的时候,需要将图片进行保存,意义是为了与用户输入的图片验证码进行对比,对比成功,才会给用户返回短信验证码

  • step3 问题分析

后端生成的图片验证码是存在哪里,谁来维护有效期,不可能一张图片一直用下去,所以将在后端生成的图片验证码,存到redis数据库中,在后端进行验证的时候,就从redis中取出这个值,与前端用户输入的值进行对比即可;但是对于多个用户来说同一时间向我发送获取图片验证码时,该怎么去判断谁是谁的,所以要将图片验证码进行编号处理,来分辨是属于哪个用户的图片验证码,那么就需要在用户发起短信验证码请求的携带参数里面除了填写的图片验证码,还需要携带一个用户编号,因此对于后端服务器来说,除了生成图片验证码的值,还需要生成一个对应验证码的编码,一起保存到redis数据库中,还需要将验证码值和编码返回给前端用户,那么就需要从返回的响应体中取解析编码,这样做太麻烦了,为了减轻后端的压力,将不再由后端去生成这个编码了,而是由前端在一开始就去生成这个编号,再前端向后端服务器发起获取图片验证码请求的时候携带一个编码参数,然后后端将编码和图片验证码的值一起存到redis数据库中

  • step4 在ihome/api_1_0目录下创建一个verify_code.py文件,将图片验证码以及短信验证码放在这个文件里面进行使用
  • step5 使用restful风格构建前端向后端发起图片验证码请求地址
GET http://127.0.0.1:5000/api/v1.0/image_codes/<image_code_id>

2.图片验证码后端接口编写

  • step1 将图片验证码工具包captcha拷贝到ihome/utils目录下
  • step2 在verify.py中导入captcha包中的captcha模块中的captcha对象
from ihome.utils.captcha.captcha import captcha
  • step3 通过调用captcha对象中的generate_captcha方法来获取生成的验证码名字,文本内容,以及图片二进制数据
name, text, image_data = captcha.generate_captcha()
  • step4 选择存储数据类型,将验证码的文本内容以及编码存到redis数据库中,并设置有效期

可以使用哈希格式进行存储,但是无法设置单个图片的有效期

示例:

"image_codes": {"id1":"abc", "":""} 哈希  hset("image_codes", "id1", "abc")  hget("image_codes", "id1")

使用字符串格式对数据进行存储,以编码作为key,以文本内容作为value值进行存储即可

示例:

"image_code_编号1": "真实值"
"image_code_编号2": "真实值"
redis_store.set("image_code_%s" % image_code_id, text)
redis_store.expire("image_code_%s" % image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES)
  • step5 在verify.py中导入redis数据库连接对象,然后将编码和文本内容存到redis数据库
from ihome import redis_store

redis_store.set("image_code_%s" %image_code_id, text)
  • step6 设置图片验证码有效期为三分钟,首先在ihome目录下创建一个constants.py文件,用于存放常量
redis_store.expire("image_code_%s" %image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES)

设置值和有效期一步到位

redis_store.setex("image_code_%s" %image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
  • step7 对于数据库连接,可能会出现连接错误以及连接不上等问题,所以需要捕获异常,并且将捕获到的异常保存到日志中
current_app.logger.error(e)
  • step8 当出现异常后,需要返回错误信息的json数据,先将工程项目定义好的response_code.py响应状态码文件,拷贝到utils中

return jsonify(errno=RET.DBERR, errmsg="save image code failed")
  • step9 没有出现异常,则先通过make_response构造图片image_data数据响应体对象,再设置该响应体对象的请求头中的Content-Type为图片格式jpg,返回给前端

 3.开发流程与编写接口文档

  • step1 开发流程

1. 分析需求
           2. 编写代码
           3. 编写单元测试
           4. 自测
           5. 编写接口文档
           6. 提测代码

  • step2 编写接口文档
接口文档

1. 接口名字
2. 描述(描述清楚接口的功能)
3. url
4. 请求方式
5. 传入参数
6. 返回值

接口:获取图片验证码

描述:前端访问,可以获取到验证码图片

url: /api/v1.0/image_codes/<image_code_id>

请求方式: GET

传入参数:
    格式:路径参数 (参数是查询字符串、请求体的表单、json、xml)

    名字             类型       是否必须      说明
   image_code_id    字符串       是         验证码图片的编号

返回值:
    格式: 正常:图片, 异常:json

    名字             类型       是否必传      说明
    errno          字符串         否        错误代码
    errmsg         字符串         否        错误内容

    实例:
    '{"errno": "4001", "errmsg": "保存图片验证码失败"}'

四丶测试后端verify_code接口是否正确

1.需要在api_1_0/init中导入我们写的接口文件verify_code让蓝图知道有一个verify_code的模块

from . import verify_code

2.运行程序

python manage.py runserver

3.在浏览器中输入http://127.0.0.1:5000/api/v1.0/image_codes/123,成功显示出验证码图片

4.查看程序运行日志

5.此时查看redis数据库中,会发现出现了一个image_code_123的键,获取该键的值就是图片验证码的文本值,说明我们写的后端接口没问题

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 ...

随机推荐

  1. vue.js路由vue-router(一)——简单路由基础

    前言 vue.js除了拥有组件开发体系之外,还有自己的路由vue-router.在没有使用路由之前,我们页面的跳转要么是后台进行管控,要么是用a标签写链接.使用vue-router后,我们可以自己定义 ...

  2. 10G安装DataGuard

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

  3. 使用LVS 实现负载均衡的原理。

    LVS 负载均衡 负载均衡集群是 Load Balance 集群.是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端提供服务的一种方式.常用 的负载均衡. 开源软件有Nginx. ...

  4. 洛谷 P1705 爱与愁过火

    P1705 爱与愁过火 题目背景 (本道题目隐藏了两首歌名,找找看哪~~~) <爱与愁的故事第一弹·heartache>第三章. 爱与愁大神说这是ta的伤心指数,只不过现在好很多了,翻译只 ...

  5. [React] Stop Memory Leaks with componentWillUnmount Lifecycle Method in React

    In this lesson we'll take a stopwatch component we built in another lesson and identify and fix a me ...

  6. 4.2.2 MINUS

    4.2.2 MINUS正在更新内容,请稍后

  7. [UnityUI]循环滑动列表

    效果图: 使用的是UGUI和DOTween 当中比較关键的是循环滑动和层次排序: 1.循环滑动:这里先如果显示五张图片.分别标记为0,1,2,3,4,那么当向左滑动时,序列就变为1,2,3,4,0,这 ...

  8. ubuntu-删除内核

    今天进入公司第一天,公司需要给电脑安装ubuntu,这个是由it部门帮忙安装的.但是,我不小心升级了内核版本,接下来就悲剧了,因为内核版本升级以后,直接导致了环境错误,很多公司内部使用的工具都不能用了 ...

  9. Icomparer和Icomparable集合排序

    c#中实现对象集合的排序可以使用ArrayList中的Sort()方法,而有比较才能谈排序,因为不是基本类型(如string ,int.double......等)所以.NET Framework不可 ...

  10. c# List集合学习

    1---集合,可以理解成容器 泛型集合 非泛型集合2---使用集合用到的命名空间 using System.Collections.Generic;3---集合是如何来的?集合的前辈是数组,数组在内存 ...