前言

有人会有疑问,不是已经连上了mysql数据库了吗,为什么还要用redis数据库?有时候用户访问网页的时候,会产生一些临时性的数据,如验证码等,如果使用mysql存储,那么还要另外新建一张表,还要定时清理表中的验证码,使用mysql操作太麻烦了。正好redis可以解决这个问题,下面通过生成验证码的例子来学习一下。


一、环境

python 3.7
flask 2.0.2

二、使用步骤

本篇博客代码接着上篇博客flask使用装饰器继续写,文件目录如下
在这里插入图片描述

1.安装redis

1.下载

因为我使用windows系统,所以用的redis的windows版本,下载地址:https://github.com/tporadowski/redis/releases,打不开的也可以在百度云里下:https://pan.baidu.com/s/14XhuWY8W54iUbNZNk7MJcQ ,提取码:1z12。
下载完之后解压即可。
里面的文件如下:
在这里插入图片描述

2.运行

用cmd打开对应目录,输入命令运行redis服务器:

redis-server

看到下图说明redis运行成功
在这里插入图片描述
再输入命令运行redis客户端(之前的cmd窗口不要关,另开一个cmd窗口):

redis-cli

运行结果:
在这里插入图片描述
自此,redis准备完成。

2.安装并使用redis包

1.安装

python有专门操作redis的包,先下载:

pip install redis

2.使用

先在config.py添加redis的配置信息
config.py

from flask_teach.common import random_num


# 配置信息类
class Config(object):
	......

    # 加了这两句,redis配置信息,主机地址和端口号
    REDIS_HOST = '127.0.0.1'
    REDIS_PORT = 6379

之后在flask_teach下的__init__.py里面创建一个redis对象:
flask_teach/init.py

# 加了这句,引入redis
from redis import StrictRedis

from config import Config

......

# 加了这句,创建redis对象
redis_store = StrictRedis(host=Config.REDIS_HOST, port=Config.REDIS_PORT, decode_responses=True)

......


# 创建app
def create_app():
	......

再在test目录下的views.py编写验证码生成视图:
test/views.py

from flask import request, render_template, redirect, session, url_for, jsonify

from . import test_blue

from flask_teach import db, models, redis_store
from flask_teach.common import random_num

......

# 返回验证码
@test_blue.route('/valid_code')
def valid_code():
    # 获取数据
    phone = request.args.get('phone')
    print(phone)
    try:
        # 生成四位随机数字字母作为验证码
        code = random_num(4)
        # 将验证码保存到redis中,第一个参数是key,第二个参数是value,第三个参数表示60秒后过期
        redis_store.set('valid_code:{}'.format(phone), code, 60)
        # 这里用输出验证码来代替短信发送验证码
        print(code)
        return jsonify(status="成功", msg="验证码发送成功")
    except Exception as e:
        return jsonify(status='失败', msg="验证码发送失败")

为了使用验证码,原来的登录视图和login.html也要做些修改:
登录视图:

from flask import request, render_template, redirect, session, url_for, jsonify

from . import test_blue

from flask_teach import db, models, redis_store
# 引入装饰器
from flask_teach.decorators import decorator_login
from flask_teach.common import random_num


# 登录视图
@test_blue.route('/login', methods=['POST', 'GET'])
def login():
    content = {
        'data': '',
        'msg': ''
    }
    # 根据请求方式的不同返回不同结果
    if request.method == 'GET':
        return render_template('test/login.html', content=content)
    else:
        # 获取传过来的表单数据
        name = request.form['name']     # 用户名
        password = request.form['password']     # 密码
        phone = request.form['phone']       # 电话号码
        val_code = request.form['valid_code']   # 验证码

        # 获取保存在redis里面的验证码
        redis_code = redis_store.get('valid_code:{}'.format(phone))

        # 验证码校验不通过
        # 判断验证码是否过期
        if not redis_code:
            msg = '验证码已过期'

        # 判断验证码是否错误
        elif val_code.lower() != redis_code.lower():
            msg = '验证码错误'

        # 验证码校验通过,开始查找用户信息
        elif val_code.lower() == redis_code.lower():
            # 查找对应用户
            test = models.Test.query.filter_by(name=name).first()
            # 用户存在,比较密码
            if test:
                # 密码正确,登录成功,跳转到首页
                if test.password == password:
                    # 将用户名存到session中,方便后面使用
                    session['name'] = name
                    # 重定向到首页
                    return redirect('/test/index')

            # 用户不存在或者密码错误返回错误信息
            return '用户名不存在或者密码错误'

        content = {
            'data': request.form,
            'msg': msg
        }

        return render_template('/test/login.html', content=content)

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <!-- 引入jquery -->
    <script src="../../static/js/jquery-3.6.0.min.js"></script>
</head>
<body>
<form action="/test/login" method="post">
    用户名:<input type="text" name="name" value="{{content.data.name}}"><br>
    密码:<input type="password" name="password" value="{{content.data.password}}"><br>
    手机号:<input type="text" name="phone" id="phone" value="{{content.data.phone}}"><br>
    验证码:<input type="text" name="valid_code" id="valid_code">{{content.msg}}
    <input type="button" id="get_valid_code" value="获取验证码"><br>
    <input type="submit" value="登录">
</form>
<script>
    $(function(){
        // 监听获取验证码按钮点击
        $('#get_valid_code').click(function () {

            var btn = $(this);
            // 获取手机号
            let phone = $('#phone').val();
			// 有手机号才能获取验证码
            if(phone){
            	// 使验证码按钮不可点击
                btn.prop('disabled', true);
                // 发送请求,后端模拟向对应手机号发送验证码
                $.ajax({
                    // 请求方式
                    type: 'GET',
                    // 请求媒体类型
                    contentType: 'application/json;charset=UTF-8',
                    // 请求地址
                    url: 'http://127.0.0.1:5000/test/valid_code?phone=' + phone,
                    // 请求成功
                    success: function (result) {
                        alert(result.msg)
                    },
                    // 请求失败,包含具体错误信息
                    error: function (e) {
                        alert(e.status);
                        alert(e.responseText);
                    }
                })
                // 倒计时秒数
                var sec = 60;
                // 创建定时器对象
                var timer = setInterval(
                    function () {
                    	// 秒数大于0,继续倒计时
                        if(sec>0) {
                            console.log($(this));
                            btn.val(String(sec) + '秒后再次发送');
                            sec--;
                        }else{
                        	// 秒数小于0,重置秒数,使验证码按钮可以点击,并且清除定时器,使秒数不再倒计时
                            sec = 60;
                            btn.val('获取验证码');
                            btn.prop('disabled', false);
                            // 清除定时器
                            clearInterval(timer);
                        }
                    }, 1000);
            }else{
                alert("请输入手机号!!!")
            }
        })

    })
</script>
</body>
</html>

注意:login.html里面用了jquery,要自己下载,下载地址https://jquery.com/download/,推荐下载下图的。点击了之后,打开的时候是一个网页(反正我是这样),自己新建一个js文件,再把里面的代码复制粘贴到自己的js文件即可。
在这里插入图片描述
我的js放置的目录,static文件中必须在这个位置,否则找不到。或者改static_folder文件。
在这里插入图片描述

运行

点击发送验证码:
在这里插入图片描述
到后台查看输出的验证码:
在这里插入图片描述
输入验证码后点击登录:
在这里插入图片描述
在redis里面也能看到对应验证码:
在这里插入图片描述
60秒后再次查找就找不到了:
在这里插入图片描述
再次输入验证码登录显示已过期:在这里插入图片描述
大功告成,有什么问题欢迎在评论区留言。

下一篇博客flask文件上传文件

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐