翼度科技»论坛 编程开发 python 查看内容

Flask Session 登录认证模块

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
Flask 框架提供了强大的 Session 模块组件,为 Web 应用实现用户注册与登录系统提供了方便的机制。结合 Flask-WTF 表单组件,我们能够轻松地设计出用户友好且具备美观界面的注册和登录页面,使这一功能能够直接应用到我们的项目中。本文将深入探讨如何通过 Flask 和 Flask-WTF 构建一个完整的用户注册与登录系统,以及如何对页面进行优化美化,提高用户体验。通过这一系统,用户能够方便注册账户、安全登录,并且我们能够有效管理用户的会话信息,为 Web 应用的用户管理提供一种高效的解决方案。
什么是Session机制?
Session 是一种在 Web 应用中用于存储用户特定信息的机制。它允许在用户访问网站时存储和检索信息,以便在用户的不同请求之间保持状态。Session 机制在用户登录、购物网站、个性化设置等场景中得到广泛应用,它为用户提供了更加连贯和个性化的体验。在 Flask 中,通过 Flask Session 模块可以方便地使用 Session ,实现用户状态的维护和管理。
在 Web 开发中,HTTP 协议是无状态的,即每个请求都是独立的,服务器不会记住之前的请求信息。为了解决这个问题,引入了 Session 机制。基本思想是在用户访问网站时,服务器生成一个唯一的 Session ID,并将这个 ID 存储在用户的浏览器中(通常通过 Cookie)。同时,服务器端会保存一个映射,将 Session ID 与用户的相关信息关联起来,这样在用户的后续请求中,服务器就能根据 Session ID 找到相应的用户信息,从而实现状态的保持。
Session 的认证流程通常包括以下步骤:

  • 用户登录: 用户通过提供用户名和密码进行登录。在登录验证成功后,服务器为该用户创建一个唯一的 Session ID,并将这个 ID 存储在用户浏览器的 Cookie 中。
  • Session 存储: 服务器端将用户的相关信息(如用户 ID、权限等)与 Session ID 关联起来,并将这些信息存储在服务器端的 Session 存储中。Session 存储可以是内存、数据库或其他持久化存储方式。
  • Session ID 传递: 服务器将生成的 Session ID 发送给用户浏览器,通常是通过 Set-Cookie 头部。这个 Cookie 会在用户的每次请求中被包含在 HTTP 头中。
  • 后续请求: 用户在后续的请求中会携带包含 Session ID 的 Cookie。服务器通过解析请求中的 Session ID,从 Session 存储中检索用户的信息,以恢复用户的状态。
  • 认证检查: 服务器在每次请求中检查 Session ID 的有效性,并验证用户的身份。如果 Session ID 无效或过期,用户可能需要重新登录。
  • 用户登出: 当用户主动注销或 Session 过期时,服务器将删除与 Session ID 关联的用户信息,用户需要重新登录。
总体而言,Session 的认证流程通过在客户端和服务器端之间传递唯一的 Session ID,实现了用户状态的持久化和管理。这种机制使得用户可以在多个请求之间保持登录状态,提供了一种有效的用户认证方式。在 Flask 中,开发者可以方便地使用 Flask 提供的 Session 模块来实现这一流程。
Session 认证基础

默认情况下,直接使用Session模块即可实现Session登录会话保持,该方式是将Session存储到内存中,程序重启后即释放,Session的设置一般可以通过使用session["username"]赋值的方式进行,如需验证该Session的可靠性,则只需要调用session.get方法即可一得到特定字段,通过对字段的判断即可实现认证机制。
如下是一个Flask后端代码,运行后通过访问http://127.0.0.1:5000进入到登录这页面。
  1. from flask import Flask,session,render_template,request,Response,redirect,url_for
  2. from functools import wraps
  3. import os
  4. app = Flask(__name__, static_folder="./template",template_folder="./template")
  5. app.config['SECRET_KEY'] = os.urandom(24)
  6. # 登录认证装饰器
  7. def login_required(func):
  8.     @wraps(func)
  9.     def wrapper(*args, **kwargs):
  10.         if session.get("username") != None and session.get("is_login") ==True:
  11.             print("登陆过则继续执行原函数")
  12.             return func(*args, **kwargs)
  13.         else:
  14.             print("没有登录则跳转到登录页面")
  15.             resp = Response()
  16.             resp.status_code=200
  17.             resp.data = ""
  18.             return resp
  19.     return wrapper
  20. @app.route("/login",methods=["GET","POST"])
  21. def login():
  22.     if request.method == "GET":
  23.         html = """
  24.                 <form action="/login" method="post">
  25.                     <p>账号: <input type="text" name="username"></p>
  26.                     <p>密码: <input type="password" name="password"></p>
  27.                     <input type="submit" value="登录">
  28.                 </form>
  29.                 """
  30.         return html
  31.     if request.method == "POST":
  32.         get_dict = request.form.to_dict()
  33.         get_username = get_dict['username']
  34.         get_password = get_dict['password']
  35.         if (get_username == "lyshark" or get_username == "admin") and get_password == "123123":
  36.             session["username"] = get_username
  37.             session["is_login"] = True
  38.             print("登录完成直接跳到主页")
  39.             resp = Response()
  40.             resp.status_code=200
  41.             resp.data = ""
  42.             return resp
  43.         else:
  44.             return "登陆失败"
  45.     return "未知错误"
  46. # 主页菜单
  47. @app.route("/index",methods = ["GET","POST"])
  48. @login_required
  49. def index():
  50.     username = session.get("username")
  51.     return "用户 {} 您好,这是主页面".format(username)
  52. # 第二个菜单
  53. @app.route("/get",methods = ["GET","POST"])
  54. @login_required
  55. def get():
  56.     username = session.get("username")
  57.     return "用户 {} 您好,这是子页面".format(username)
  58. @app.route("/logout",methods = ["GET","POST"])
  59. @login_required
  60. def logout():
  61.     username = session.get("username")
  62.     # 登出操作
  63.     session.pop("username")
  64.     session.pop("is_login")
  65.     session.clear()
  66.     return "用户 {} 已注销".format(username)
  67. if __name__ == '__main__':
  68.     app.run()
复制代码
程序运行后,当用户访问http://127.0.0.1:5000地址则会跳转到login登陆页面,此时如果用户第一次访问则会输出如下所示的登陆信息;

通过输入正确的用户名lyshark和密码123123则可以登录成功,此处登录的用户是lyshark如下图。

通过输入不同的用户登录会出现不同的页面提示信息,如下图则是admin的主页信息。

当我们手动输入logout时则此时会退出登录用户,后台也会清除该用户的Session,在开发中可以自动跳转到登出页面;

Session 使用数据库

通过结合 Session 与 SQLite 数据库,我们可以实现一个更完善的用户注册、登录以及密码修改功能。在这个案例中,首先,用户可以通过注册表单输入用户名、密码等信息,这些信息经过验证后将被存储到 SQLite 数据库中。注册成功后,用户可以使用相同的用户名和密码进行登录。登录成功后,我们使用 Flask 的 Session 机制将用户信息保存在服务器端,确保用户在访问其他页面时仍然处于登录状态。
为了增加更多功能,我们还可以实现密码修改的功能。用户在登录状态下,通过密码修改表单输入新的密码,我们将新密码更新到数据库中,确保用户可以安全地更改密码。这个案例综合运用了 Flask、SQLite 和 Session 等功能,为 Web 应用提供了一套完整的用户管理系统。
  1. from flask import Flask,request,render_template,session,Response
  2. import sqlite3,os
  3. from functools import wraps
  4. app = Flask(__name__)
  5. app.config['SECRET_KEY'] = os.urandom(24)
  6. # 创建数据库
  7. def UserDB():
  8.     conn = sqlite3.connect("./database.db")
  9.     cursor = conn.cursor()
  10.     create = "create table UserDB(" \
  11.              "uid INTEGER primary key AUTOINCREMENT not null unique," \
  12.              "username char(64) not null unique," \
  13.              "password char(64) not null," \
  14.              "email char(64) not null" \
  15.              ")"
  16.     cursor.execute(create)
  17.     conn.commit()
  18.     cursor.close()
  19.     conn.close()
  20. # 增删改查简单封装
  21. def RunSqlite(db,table,action,field,value):
  22.     connect = sqlite3.connect(db)
  23.     cursor = connect.cursor()
  24.     # 执行插入动作
  25.     if action == "insert":
  26.         insert = f"insert into {table}({field}) values({value});"
  27.         if insert == None or len(insert) == 0:
  28.             return False
  29.         try:
  30.             cursor.execute(insert)
  31.         except Exception:
  32.             return False
  33.     # 执行更新操作
  34.     elif action == "update":
  35.         update = f"update {table} set {value} where {field};"
  36.         if update == None or len(update) == 0:
  37.             return False
  38.         try:
  39.             cursor.execute(update)
  40.         except Exception:
  41.             return False
  42.     # 执行查询操作
  43.     elif action == "select":
  44.         # 查询条件是否为空
  45.         if value == "none":
  46.             select = f"select {field} from {table};"
  47.         else:
  48.             select = f"select {field} from {table} where {value};"
  49.         try:
  50.             ref = cursor.execute(select)
  51.             ref_data = ref.fetchall()
  52.             connect.commit()
  53.             connect.close()
  54.             return ref_data
  55.         except Exception:
  56.             return False
  57.     # 执行删除操作
  58.     elif action == "delete":
  59.         delete = f"delete from {table} where {field};"
  60.         if delete == None or len(delete) == 0:
  61.             return False
  62.         try:
  63.             cursor.execute(delete)
  64.         except Exception:
  65.             return False
  66.     try:
  67.         connect.commit()
  68.         connect.close()
  69.         return True
  70.     except Exception:
  71.         return False
  72. # 创建数据库
  73. @app.route("/create")
  74. def create():
  75.     UserDB()
  76.     return "create success"
  77. # 登录认证装饰器
  78. def login_required(func):
  79.     @wraps(func)
  80.     def wrapper(*args, **kwargs):
  81.         if session.get("username") != None and session.get("is_login") ==True:
  82.             print("登陆过则继续执行原函数")
  83.             return func(*args, **kwargs)
  84.         else:
  85.             print("没有登录则跳转到登录页面")
  86.             resp = Response()
  87.             resp.status_code=200
  88.             resp.data = ""
  89.             return resp
  90.     return wrapper
  91. # 用户注册页面
  92. @app.route("/register",methods=["GET","POST"])
  93. def register():
  94.     if request.method == "GET":
  95.         html = """
  96.                 <form action="/register" method="post">
  97.                     <p>账号: <input type="text" name="username"></p>
  98.                     <p>密码: <input type="password" name="password"></p>
  99.                     <p>邮箱: <input type="text", name="email"></p>
  100.                     <input type="submit" value="用户注册">
  101.                 </form>
  102.                 """
  103.         return html
  104.     if request.method == "POST":
  105.         username = request.form.get("username")
  106.         password = request.form.get("password")
  107.         email = request.form.get("email")
  108.         if RunSqlite("database.db","UserDB","select","username",f"username='{username}'") == []:
  109.             insert = RunSqlite("database.db","UserDB","insert","username,password,email",f"'{username}','{password}','{email}'")
  110.             if insert == True:
  111.                 return "创建完成"
  112.             else:
  113.                 return "创建失败"
  114.         else:
  115.             return "用户存在"
  116.         return "未知错误"
  117. # 用户登录模块
  118. @app.route("/login",methods=["GET","POST"])
  119. def login():
  120.     if request.method == "GET":
  121.         html = """
  122.                 <form action="/login" method="post">
  123.                     <p>账号: <input type="text" name="username"></p>
  124.                     <p>密码: <input type="password" name="password"></p>
  125.                     <input type="submit" value="登录">
  126.                 </form>
  127.                 """
  128.         return html
  129.     if request.method == "POST":
  130.         username = request.form.get("username")
  131.         password = request.form.get("password")
  132.         select = RunSqlite("database.db","UserDB","select","username,password",f"username='{username}'")
  133.         if select != []:
  134.             # 继续验证密码
  135.             if select[0][1] == password:
  136.                 session["username"] = username
  137.                 session["is_login"] = True
  138.                 print("登录完成直接跳到主页")
  139.                 resp = Response()
  140.                 resp.status_code = 200
  141.                 resp.data = ""
  142.                 return resp
  143.             else:
  144.                 return "密码不正确"
  145.         else:
  146.             return "用户不存在"
  147.     return "未知错误"
  148. # 修改密码
  149. @app.route("/modify",methods=["GET","POST"])
  150. @login_required
  151. def modify():
  152.     if request.method == "GET":
  153.         html = """
  154.                 <form action="/modify" method="post">
  155.                     <p>新密码: <input type="password" name="new_password"></p>
  156.                     <input type="submit" value="修改密码">
  157.                 </form>
  158.                 """
  159.         return html
  160.     if request.method == "POST":
  161.         username = session.get("username")
  162.         new_password = request.form.get("new_password")
  163.         update = RunSqlite("database.db","UserDB","update",f"username='{username}'",f"password='{new_password}'")
  164.         if update == True:
  165.             # 登出操作
  166.             session.pop("username")
  167.             session.pop("is_login")
  168.             session.clear()
  169.             print("密码已更新,请重新登录")
  170.             resp = Response()
  171.             resp.status_code = 200
  172.             resp.data = ""
  173.             return resp
  174.         else:
  175.             return "密码更新失败"
  176.     return "未知错误"
  177. # 主页菜单
  178. @app.route("/index",methods = ["GET","POST"])
  179. @login_required
  180. def index():
  181.     username = session.get("username")
  182.     return "用户 {} 您好,这是主页面".format(username)
  183. # 第二个菜单
  184. @app.route("/get",methods = ["GET","POST"])
  185. @login_required
  186. def get():
  187.     username = session.get("username")
  188.     return "用户 {} 您好,这是子页面".format(username)
  189. @app.route("/logout",methods = ["GET","POST"])
  190. @login_required
  191. def logout():
  192.     username = session.get("username")
  193.     # 登出操作
  194.     session.pop("username")
  195.     session.pop("is_login")
  196.     session.clear()
  197.     return "用户 {} 已注销".format(username)
  198. if __name__ == '__main__':
  199.     app.run(debug=True)
复制代码
案例被运行后首先通过调用http://127.0.0.1:5000/create创建database.db数据库,接着我们可以通过访问/register路径实现账号注册功能,如下我们注册lyshark密码是123123,输出效果如下所示;

通过访问/modify可实现对用户密码的修改,但在修改之前需要先通过/login页面登录后进行,否则会默认跳转到用户登录页面中;
使用WTForms登录模板

在如上代码基础上,我们着重增加一个美化登录模板,以提升用户在注册登录流程中的整体体验。通过引入WTF表单组件和Flask-WTF扩展,在前端实现了一个更友好的登录页面。
此登录模板的设计考虑了页面布局、颜色搭配、表单样式等因素,以确保用户在输入用户名和密码时感到轻松自然。同时,我们利用Flask-WTF的验证器功能,对用户输入的数据进行有效性检查,保障了用户信息的安全性。
首先,我们需要在template目录下,创建register.html前端文件,用于用户注册,并写入以下代码。
  1. <html>
  2. <head>
  3.     <link rel="stylesheet" href="https://www.lyshark.com/javascript/bootstrap/3.3.7/css/bootstrap.min.css">
  4.     <link href="https://www.lyshark.com/javascript/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
  5.     <link href="https://www.lyshark.com/javascript/other/my_login.css" rel="stylesheet" type="text/css" />
  6. </head>
  7. <body>
  8.    
  9.         
  10.             
  11.                 <form action="/register" method="post" >
  12.                     {{ form.csrf_token }}
  13.                     用 户 注 册
  14.                     
  15.                         {{ form.username }}
  16.                         <i ></i>
  17.                         <a target="_blank" href="https://www.cnblogs.com/login" ></a>
  18.                     
  19.                     
  20.                         {{ form.email }}
  21.                         <i ></i>
  22.                     
  23.                     
  24.                         {{ form.password }}
  25.                         <i ></i>
  26.                     
  27.                     
  28.                         {{ form.RepeatPassword }}
  29.                         <i ></i>
  30.                     
  31.                     {{ form.submit }}
  32.                 </form>
  33.             
  34.         
  35.    
  36. </body>
  37. </html>
复制代码
接着,继续创建login.html前端文件,用于登录账号时使用,并写入以下代码。
  1. <html>
  2. <head>
  3.     <link rel="stylesheet" href="https://www.lyshark.com/javascript/bootstrap/3.3.7/css/bootstrap.min.css">
  4.     <link href="https://www.lyshark.com/javascript/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
  5.     <link href="https://www.lyshark.com/javascript/other/my_login.css" rel="stylesheet" type="text/css" />
  6. </head>
  7.     <body>
  8.         
  9.             
  10.                
  11.                     <form action="/login" method="post" >
  12.                         {{ form.csrf_token }}
  13.                         用 户 登 录
  14.                         
  15.                             {{ form.username }}
  16.                             <i ></i>
  17.                         
  18.                         
  19.                             {{ form.password }}
  20.                             <i ></i>
  21.                             <a target="_blank" href="https://www.cnblogs.com/#" ></a>
  22.                         
  23.                         
  24.                             <button type="submit" >登 录 后 台</button>
  25.                         
  26.                     </form>
  27.                
  28.             
  29.         
  30.     </body>
  31. </html>
复制代码
后台代码部分,我们需要在原代码的基础之上,增加对前端注册和登录页面的渲染类,此处使用flask_wtf组件实现渲染生成,具体代码如下。
  1. from flask import Flask,request,render_template,session,Response
  2. from functools import wraps
  3. import sqlite3,os
  4. from flask_wtf import FlaskForm
  5. from wtforms import widgets,validators
  6. from wtforms.validators import DataRequired,Regexp,DataRequired, Length, Email, EqualTo, NumberRange
  7. from wtforms.fields import (StringField, PasswordField, DateField, BooleanField,DateTimeField,TimeField,
  8.                             SelectField, SelectMultipleField, TextAreaField,FloatField,HiddenField,
  9.                             RadioField, IntegerField, DecimalField, SubmitField, IntegerRangeField)
  10. # app = Flask(__name__, static_folder="./template",template_folder="./template")
  11. app = Flask(__name__)
  12. app.config["SECRET_KEY"] = "d3d3Lmx5c2hhcmsuY29t"
  13. # -----------------------------------------------------------------------------
  14. # 创建数据库
  15. def UserDB():
  16.     conn = sqlite3.connect("database.db")
  17.     cursor = conn.cursor()
  18.     create = "create table UserDB(" \
  19.              "uid INTEGER primary key AUTOINCREMENT not null unique," \
  20.              "username char(64) not null unique," \
  21.              "password char(64) not null," \
  22.              "email char(64) not null" \
  23.              ")"
  24.     cursor.execute(create)
  25.     conn.commit()
  26.     cursor.close()
  27.     conn.close()
  28. # 增删改查简单封装
  29. def RunSqlite(db,table,action,field,value):
  30.     connect = sqlite3.connect(db)
  31.     cursor = connect.cursor()
  32.     # 执行插入动作
  33.     if action == "insert":
  34.         insert = f"insert into {table}({field}) values({value});"
  35.         if insert == None or len(insert) == 0:
  36.             return False
  37.         try:
  38.             cursor.execute(insert)
  39.         except Exception:
  40.             return False
  41.     # 执行更新操作
  42.     elif action == "update":
  43.         update = f"update {table} set {value} where {field};"
  44.         if update == None or len(update) == 0:
  45.             return False
  46.         try:
  47.             cursor.execute(update)
  48.         except Exception:
  49.             return False
  50.     # 执行查询操作
  51.     elif action == "select":
  52.         # 查询条件是否为空
  53.         if value == "none":
  54.             select = f"select {field} from {table};"
  55.         else:
  56.             select = f"select {field} from {table} where {value};"
  57.         try:
  58.             ref = cursor.execute(select)
  59.             ref_data = ref.fetchall()
  60.             connect.commit()
  61.             connect.close()
  62.             return ref_data
  63.         except Exception:
  64.             return False
  65.     # 执行删除操作
  66.     elif action == "delete":
  67.         delete = f"delete from {table} where {field};"
  68.         if delete == None or len(delete) == 0:
  69.             return False
  70.         try:
  71.             cursor.execute(delete)
  72.         except Exception:
  73.             return False
  74.     try:
  75.         connect.commit()
  76.         connect.close()
  77.         return True
  78.     except Exception:
  79.         return False
  80. # -----------------------------------------------------------------------------
  81. # 生成用户注册表单
  82. class RegisterForm(FlaskForm):
  83.     username = StringField(
  84.         validators=[
  85.             DataRequired(message='用户名不能为空'),
  86.             Length(min=1, max=15, message='用户名长度必须大于%(min)d且小于%(max)d')
  87.         ],
  88.         widget=widgets.TextInput(),
  89.         render_kw={'class': 'form-control', "placeholder":"输入注册用户名"}
  90.     )
  91.     email = StringField(
  92.         validators=[validators.DataRequired(message='邮箱不能为空'),validators.Email(message="邮箱格式输入有误")],
  93.         render_kw={'class':'form-control', "placeholder":"输入Email邮箱"}
  94.     )
  95.     password = PasswordField(
  96.         validators=[
  97.             validators.DataRequired(message='密码不能为空'),
  98.             validators.Length(min=5, message='用户名长度必须大于%(min)d'),
  99.             validators.Regexp(regex="[0-9a-zA-Z]{5,}",message='密码不允许使用特殊字符')
  100.         ],
  101.         widget=widgets.PasswordInput(),
  102.         render_kw={'class': 'form-control', "placeholder":"输入用户密码"}
  103.     )
  104.     RepeatPassword = PasswordField(
  105.         validators=[
  106.             validators.DataRequired(message='密码不能为空'),
  107.             validators.Length(min=5, message='密码长度必须大于%(min)d'),
  108.             validators.Regexp(regex="[0-9a-zA-Z]{5,}",message='密码不允许使用特殊字符'),
  109.             validators.EqualTo("password",message="两次密码输入必须一致")
  110.         ],
  111.         widget=widgets.PasswordInput(),
  112.         render_kw={'class': 'form-control', "placeholder":"再次输入密码"}
  113.     )
  114.     submit = SubmitField(
  115.         label="用 户 注 册", render_kw={ "class":"btn btn-success" }
  116.     )
  117. # 生成用户登录表单
  118. class LoginForm(FlaskForm):
  119.     username = StringField(
  120.         validators=[
  121.             validators.DataRequired(message=''),
  122.             validators.Length(min=4, max=15, message=''),
  123.             validators.Regexp(regex="[0-9a-zA-Z]{4,15}", message='')
  124.         ],
  125.         widget=widgets.TextInput(),
  126.         render_kw={"class":"form-control", "placeholder":"请输入用户名或电子邮件"}
  127.     )
  128.     password = PasswordField(
  129.         validators=[
  130.             validators.DataRequired(message=''),
  131.             validators.Length(min=5, max=15,message=''),
  132.             validators.Regexp(regex="[0-9a-zA-Z]{5,15}",message='')
  133.         ],
  134.         widget=widgets.PasswordInput(),
  135.         render_kw={"class":"form-control", "placeholder":"请输入密码"}
  136.     )
  137. # -----------------------------------------------------------------------------
  138. # 创建数据库
  139. @app.route("/create")
  140. def create():
  141.     UserDB()
  142.     return "create success"
  143. # 登录认证装饰器
  144. def login_required(func):
  145.     @wraps(func)
  146.     def wrapper(*args, **kwargs):
  147.         if session.get("username") != None and session.get("is_login") ==True:
  148.             print("登陆过则继续执行原函数")
  149.             return func(*args, **kwargs)
  150.         else:
  151.             print("没有登录则跳转到登录页面")
  152.             resp = Response()
  153.             resp.status_code=200
  154.             resp.data = ""
  155.             return resp
  156.     return wrapper
  157. # 用户注册页面
  158. @app.route("/register",methods=["GET","POST"])
  159. def register():
  160.     form = RegisterForm(csrf_enabled = True)
  161.     if request.method == "POST":
  162.         if form.validate_on_submit():
  163.             username = form.username.data
  164.             password = form.RepeatPassword.data
  165.             email = form.email.data
  166.             print("用户: {} 邮箱: {}".format(username,email))
  167.             if RunSqlite("database.db", "UserDB", "select", "username", f"username='{username}'") == []:
  168.                 insert = RunSqlite("database.db", "UserDB", "insert", "username,password,email",
  169.                                    f"'{username}','{password}','{email}'")
  170.                 if insert == True:
  171.                     return "创建完成"
  172.                 else:
  173.                     return "创建失败"
  174.             else:
  175.                 return "用户存在"
  176.     return render_template("register.html", form=form)
  177. # 用户登录页面
  178. @app.route("/login",methods=["GET","POST"])
  179. def login():
  180.     form = LoginForm(csrf_enabled = True)
  181.     if request.method == "POST":
  182.         username = form.username.data
  183.         password = form.password.data
  184.         select = RunSqlite("database.db","UserDB","select","username,password",f"username='{username}'")
  185.         if select != []:
  186.             # 继续验证密码
  187.             if select[0][1] == password:
  188.                 session["username"] = username
  189.                 session["is_login"] = True
  190.                 print("登录完成直接跳到主页")
  191.                 resp = Response()
  192.                 resp.status_code = 200
  193.                 resp.data = ""
  194.                 return resp
  195.             else:
  196.                 return "密码不正确"
  197.         else:
  198.             return "用户不存在"
  199.     return render_template("login.html", form=form)
  200. # 修改密码
  201. @app.route("/modify",methods=["GET","POST"])
  202. @login_required
  203. def modify():
  204.     if request.method == "GET":
  205.         html = """
  206.                 <form action="/modify" method="post">
  207.                     <p>新密码: <input type="password" name="new_password"></p>
  208.                     <input type="submit" value="修改密码">
  209.                 </form>
  210.                 """
  211.         return html
  212.     if request.method == "POST":
  213.         username = session.get("username")
  214.         new_password = request.form.get("new_password")
  215.         update = RunSqlite("database.db","UserDB","update",f"username='{username}'",f"password='{new_password}'")
  216.         if update == True:
  217.             # 登出操作
  218.             session.pop("username")
  219.             session.pop("is_login")
  220.             session.clear()
  221.             print("密码已更新,请重新登录")
  222.             resp = Response()
  223.             resp.status_code = 200
  224.             resp.data = ""
  225.             return resp
  226.         else:
  227.             return "密码更新失败"
  228.     return "未知错误"
  229. # 主页菜单
  230. @app.route("/index",methods = ["GET","POST"])
  231. @login_required
  232. def index():
  233.     username = session.get("username")
  234.     return "用户 {} 您好,这是主页面".format(username)
  235. # 第二个菜单
  236. @app.route("/get",methods = ["GET","POST"])
  237. @login_required
  238. def get():
  239.     username = session.get("username")
  240.     return "用户 {} 您好,这是子页面".format(username)
  241. @app.route("/logout",methods = ["GET","POST"])
  242. @login_required
  243. def logout():
  244.     username = session.get("username")
  245.     # 登出操作
  246.     session.pop("username")
  247.     session.pop("is_login")
  248.     session.clear()
  249.     return "用户 {} 已注销".format(username)
  250. if __name__ == '__main__':
  251.     app.run(debug=True)
复制代码
目录结果如下图所示;

当用户访问/register时,则可以看到通过flask_wtf渲染后的用户注册页面,如下图所示;

用户访问/login时,则是用户登录页面,如下图所示;


来源:https://www.cnblogs.com/LyShark/p/17858903.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具