登录

登录的流程是这样的,用户在登录界面首先输入邮箱和密码,然后提交到视图函数中,视图函数验证邮箱和密码是否正确,如果正确,则把能识别用户的数据添加到 cookie 中,再返回给浏览器。当浏览器下次再访问本网站下的其他页面时,会自动携带 cookie,我们就能知道这个请求是哪个用户发出的。在 blueprints/user.py 中已经定义了一个非常简单的 login 视图函数,login 视图函数与 register 一样,也是同时支持 GET 和 POST 方法,在选用 GET 时返回登录模板,我们将 login 视图函数代码修改如下。

@bp.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template("front/login.html")
    else:
        pass

下面在浏览器中访问 http://127.0.0.1:5000/user/login ,即可看到如图 9-28 所示的界面。

image 2025 01 22 15 04 14 255
Figure 1. 图9-28 登录界面

同样,在 templates/front/login.html 中的 form 标签下,添加 csrf_token 的 input 标签,以及渲染表单验证错误信息,代码如下。

image 2025 01 22 15 17 03 361

接着在 forms/user.py 中,添加一个登录表单 LoginForm,代码如下。

class LoginForm(BaseForm):
    email = StringField(
        validators=[Email(message="请输入正确格式的邮箱!")]
    )
    password = StringField(
        validators=[Length(min=6, max=20, message="请输入正确长度的密码!")]
    )
    remember = BooleanField()

回到 blueprint/user.py 的 login 视图函数中,针对 POST 请求,添加以下代码。

image 2025 01 22 15 18 35 107

上述代码中,我们首先判断邮箱是否存在,然后判断密码是否正确。如果两个条件都满足,就认为是登录成功,然后把 user.id 存储在 session 中,因为 Flask 中的 session 默认是加密后存储在 cookie 中的,这也就意味着 user.id 会被加密存放到 cookie 中并返回给浏览器。

在登录页面中,我们添加了一个 “记住我” 复选框,如果用户选中 “记住我” 复选框,则应该让 cookie 过期时间长一点(默认情况是浏览器关闭时,cookie 就会自动过期),通过设置 session.permanent=True 来实现,默认过期时间是 31 天,如果想自定义过期时间,可以在配置中添加参数 PERMANENT_SESSION_LIFETIME,这个参数的类型为 timedelta。如设置 7 天过期,那么在 config.py 的 BaseConfig 中添加如下代码。

from datetime import timedelta

class BaseConfig:
    ...
    PERMANENT_SESSION_LIFETIME = timedelta(days=7)

如果登录成功则让页面跳转到首页,为了确保登录成功后代码不报错,我们在 blueprints/front.py 中添加一个 index 视图函数,代码如下。

...
@bp.route("/")
def index():
    return "index"

在浏览器中访问 http://127.0.0.1:5000/user/login ,然后输入邮箱和密码,即可登录成功。