Python-Flask构建用户注册登录后端逻辑架构

╰半橙微兮° 2023-01-02 06:30 269阅读 0赞

Python-Flask构建用户注册登录后端逻辑架构

1、项目结构
在这里插入图片描述
2、app.py

  1. from flask import Flask,render_template
  2. from controller.user_controller import user_controller
  3. from datetime import timedelta
  4. import os
  5. app=Flask(__name__)
  6. app.register_blueprint(user_controller)
  7. app.config['JSON_AS_ASCII'] = False
  8. app.config['SECRET_KEY'] = os.urandom(24) #设置为24位的字符,每次运行服务器都是不同的,所以服务器启动一次上次的session就清除。
  9. app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30) #设置session的保存时间。
  10. @app.route('/')
  11. def index():
  12. return render_template('index.html')
  13. if __name__ == "__main__":
  14. #在生产环境中host='0.0.0.0'
  15. app.run(host='127.0.0.1',port=5020,debug=False)

3、user_controller

  1. from flask import Flask,Blueprint,request,render_template,session
  2. from dao.userdao import UserDAO
  3. from entity.user_entity import UserEntity
  4. user_controller=Blueprint('user_controller',__name__)
  5. userdao=UserDAO()
  6. userentity=UserEntity()
  7. @user_controller.route('/login',methods=['POST'])
  8. def login():
  9. info=''
  10. userentity.telphone=request.form['telphone']
  11. userentity.password=request.form['password']
  12. res=userdao.GetLoginInfo(userentity)
  13. if res==None:
  14. info='无用户信息,请注册'
  15. return render_template('index.html',info=info)
  16. elif res[0]==userentity.password:
  17. info='登录成功'
  18. session['telphone']=userentity.telphone
  19. return render_template('index.html',info=info)
  20. else:
  21. info='登录失败'
  22. return render_template('index.html',info=info)
  23. return render_template('index.html',info='Unknow Error!!!')
  24. @user_controller.route('/register',methods=['POST'])
  25. def register():
  26. info=''
  27. userentity.telphone=request.form['telphone']
  28. userentity.password=request.form['password']
  29. password_again=request.form['password_again']
  30. res=userdao.GetSameInfo(userentity)
  31. if res:
  32. info='手机号已被使用,请更换手机号重试'
  33. return render_template('index.html',info=info)
  34. elif userentity.password!=password_again:
  35. info='两次密码不一致'
  36. return render_template('index.html',info=info)
  37. else:
  38. info='注册成功'
  39. userdao.CreateUser(userentity)
  40. return render_template('index.html',info=info)
  41. return render_template('index.html',info='Unknow Error!!!')
  42. @user_controller.route('/exit',methods=['GET'])
  43. def exit():
  44. info=''
  45. res=session.get('telphone')
  46. if res==None:
  47. info='未登录'
  48. return render_template('index.html',info=info)
  49. else:
  50. session['telphone']=None
  51. info='账号已成功注销'
  52. return render_template('index.html',info=info)
  53. return render_template('index.html',info='Unknow Error!!!')

4、basedao

  1. import pymysql # 导入数据的api包
  2. from logger.syslogger import logger
  3. #数据库访问封装的基类
  4. class BaseDAO():
  5. # 1. 这些参数做私有化,就体现了封装安全性的好处
  6. def __init__(self, host='IP', name='root', pwd='PWD', port='3306', schema='talk_system', charset='utf8mb4'):
  7. self.__host = host
  8. self.__name = name
  9. self.__pwd = pwd
  10. self.__port = port
  11. self.__schema = schema
  12. self.__charset = charset
  13. self.__conn = None
  14. self.__cursor = None
  15. pass
  16. # 2. 编写建立数据库连接的公有方法(通用的)
  17. def getConnection(self):
  18. try:
  19. self.__conn = pymysql.connect(self.__host, self.__name, self.__pwd, self.__schema, charset=self.__charset)
  20. except (pymysql.MySQLError, pymysql.DatabaseError, Exception):
  21. logger.error("数据库连接异常:" + self.__host)
  22. pass
  23. self.__cursor = self.__conn.cursor()
  24. pass
  25. # 3. 封装一个通用的对数据库进行操作的方法
  26. def execute(self, sql, params=None, isBatch=False):
  27. try:
  28. # self.getConnection() # 每次连接的是独立的一个连接
  29. if self.__conn and self.__cursor:
  30. if params:
  31. # print('not None')
  32. # print(parms)
  33. if isBatch:
  34. return self.__cursor.executemany(sql, params)
  35. pass
  36. else:
  37. return self.__cursor.execute(sql, params)
  38. else:
  39. return self.__cursor.execute(sql)
  40. pass
  41. except:
  42. logger.error("执行SQL:" + sql + " params:" + str(params) )
  43. self.__cursor.close()
  44. self.__conn.close()
  45. pass
  46. pass
  47. # 调用存储过程
  48. def executeProc(self, sql, params=None):
  49. try:
  50. if self.__conn and self.__cursor:
  51. if params:
  52. return self.__cursor.callproc(sql, params)
  53. else:
  54. return self.__cursor.callproc(sql)
  55. pass
  56. except:
  57. logger.error("执行SQL:" + sql + " params:" + str(params))
  58. self.__cursor.close()
  59. self.__conn.close()
  60. pass
  61. pass
  62. # 4. 为了支持事务管理,把对数据库的关闭的动作提取出来,封装成独立的方法
  63. def close(self):
  64. if self.__cursor and self.__conn:
  65. self.__cursor.close()
  66. self.__conn.close()
  67. pass
  68. # 5. 为了支持事务管理,把对数据库事务提交的动作提取出来,封装成独立的方法
  69. def commit(self):
  70. # print("----------")
  71. self.__conn.commit()
  72. pass
  73. # 6. 如果出现异常情况,事务要回滚
  74. def rollback(self):
  75. self.__conn.rollback()
  76. pass
  77. # 查询操作
  78. def fetchall(self, sql, params=None):
  79. self.execute(sql, params)
  80. return self.__cursor.fetchall()
  81. pass
  82. # 查询操作
  83. def fetchone(self, sql, params=None):
  84. self.execute(sql, params)
  85. return self.__cursor.fetchone()
  86. pass
  87. # 执行存储过程
  88. def fetchproc(self, sql, params=None):
  89. self.executeProc(sql, params)
  90. return self.__cursor.fetchall()
  91. pass
  92. pass

5、userdao

  1. from dao.basedao import BaseDAO
  2. from logger.syslogger import logger
  3. import math
  4. class UserDAO(BaseDAO):
  5. #注册查重验证
  6. def GetSameInfo(self,user):
  7. sqlSelect = "select id from user where telphone=%s;"
  8. params = (user.telphone,)
  9. try:
  10. super().getConnection()
  11. result = super().fetchone(sqlSelect,params)
  12. super().commit()
  13. return result
  14. except Exception as e:
  15. logger.error("执行SQL:" + str(sqlSelect) + " 出现异常,params:" + str(e))
  16. finally:
  17. super().close()
  18. # 新用户注册
  19. def CreateUser(self, user):
  20. try:
  21. super().getConnection()
  22. sqlCreate = "insert into user (id,telphone,password) values (NULL ,%s, %s);"
  23. params = (user.telphone,user.password)
  24. result = super().execute(sqlCreate, params)
  25. super().commit()
  26. return result
  27. except Exception as e:
  28. super().rollback()
  29. logger.error("执行SQL:" + sqlCreate + " 出现异常,params:" + params + str(e))
  30. finally:
  31. super().close()
  32. #登录验证
  33. def GetLoginInfo(self,user):
  34. sqlSelect = "select password from user where telphone=%s;"
  35. params = (user.telphone,)
  36. try:
  37. super().getConnection()
  38. result = super().fetchone(sqlSelect, params)
  39. super().commit()
  40. return result
  41. except Exception as e:
  42. logger.error("执行SQL:" + str(sqlSelect) + " 出现异常,params:" + str(e))
  43. finally:
  44. super().close()

6、user_entity

  1. class UserEntity():
  2. def __init__(self):
  3. self.__id=None
  4. self.__telphone=None
  5. self.__password=None
  6. @property
  7. def id(self):
  8. return self.__id
  9. @id.setter
  10. def id(self, id):
  11. self.__id = id
  12. @property
  13. def telphone(self):
  14. return self.__telphone
  15. @telphone.setter
  16. def telphone(self, telphone):
  17. self.__telphone = telphone
  18. @property
  19. def password(self):
  20. return self.__password
  21. @password.setter
  22. def password(self, password):
  23. self.__password = password

7、syslogger

  1. #-*- coding:utf-8 -*-
  2. ''' demo03-logging-file.py ------------------------ 日志写入文件 @Copyright: Chinasoft International·ETC '''
  3. # 导入模块
  4. import logging
  5. import os
  6. import time
  7. # 首先,创建并设置日志logger对象
  8. # 创建logger对象并设置信息源对象名称
  9. logger = logging.getLogger('mainlogger')
  10. # 设置日志的输出的输出级别
  11. logger.setLevel(logging.DEBUG)
  12. # 设置日志的输出格式
  13. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  14. # 其次,创建并设置文件处理器FileHandler对象
  15. dirPath = os.path.join(os.getcwd(), 'log')
  16. if not os.path.exists(dirPath):
  17. os.mkdir(dirPath)
  18. logFileName = time.strftime('%Y%m%d', time.localtime())+'.log'
  19. logPath = dirPath + os.sep + logFileName
  20. # 创建FileHandler对象
  21. fileHandler = logging.FileHandler(logPath)
  22. # 设置Filehandler对象的写入信息级别
  23. fileHandler.setLevel(logging.DEBUG)
  24. # 设置FileHandler对象的信息格式
  25. fileHandler.setFormatter(formatter)
  26. # 创建一个 StreamHandler对象
  27. consoleHandler = logging.StreamHandler()
  28. # 设置控制台输出的信息级别
  29. consoleHandler.setLevel(logging.DEBUG)
  30. # 设置consoleHandler对象的信息格式
  31. consoleHandler.setFormatter(formatter)
  32. # 最后,logger对象添加Handler对象替换原有默认的Handler对象
  33. logger.addHandler(fileHandler)
  34. logger.addHandler(consoleHandler)
  35. # 测试输出不同级别的日志信息
  36. ''' logger.fatal('系统崩溃或发生致命性错误,导致程序中断时需要输出的信息') logger.critical('系统资源浩劫时需要输出的信息(一般很少用到)') logger.error('系统报错异常时需要输出的信息') logger.warning("系统运行警告时需要输出的信息") logger.info("一般信息数据") logger.debug("测试调试时需要输出的信息数据") '''

8、index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document</title>
  7. </head>
  8. <body>
  9. { { info}}
  10. <h2>登录</h2>
  11. <form action="/login" method="post">
  12. <label for="username">手机号:</label>
  13. <input type="text" name="telphone" required>
  14. <label for="password">密码:</label>
  15. <input type="text" name="password" required>
  16. <button type="reset">重置</button>
  17. <button type="submit">提交</button>
  18. </form>
  19. <h2>注册</h2>
  20. <form action="/register" method="post">
  21. <label for="telphone">手机号:</label>
  22. <input type="text" name="telphone" required>
  23. <label for="password">密码:</label>
  24. <input type="text" name="password" required>
  25. <label for="password_again">密码二次确认:</label>
  26. <input type="text" name="password_again" required>
  27. <button type="reset">重置</button>
  28. <button type="submit">提交</button>
  29. </form>
  30. <a href="/exit">账号注销</a>
  31. </body>
  32. </html>

9、程序启动效果图
在这里插入图片描述——————————————————————————————————————————————
在这里插入图片描述——————————————————————————————————————————————
在这里插入图片描述——————————————————————————————————————————————
在这里插入图片描述——————————————————————————————————————————————
在这里插入图片描述——————————————————————————————————————————————
在这里插入图片描述——————————————————————————————————————————————
在这里插入图片描述——————————————————————————————————————————————
在这里插入图片描述
10、备注
这个架构只考虑最简单的登录、注册、注销逻辑,之后优化可以注重前端输入限制、placeholder、登录密码加盐Hash等等

发表评论

表情:
评论列表 (有 0 条评论,269人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java_获取当前登录用户信息

    后端获取当前登录用户信息 开发过程中,发现有很多地方需要获取当前登录的用户信息,比如新增、修改时候要记录创建人和更新人信息,如果每次操作都从数据库中获取用户信息,会增加不

    相关 用户注册登录流程

    用户注册: 1.用户填写参数,移出鼠标效验手机号,登录账号,邮箱, 2.判断用户id是否是超级管理员用户,超级管理员是不允许修改的 3.随机生成盐,用户赋值盐

    相关 移动用户登录&注册案例

    用的是TypeScript语言,主要是展示相关的思想逻辑,而不是语法。会说明注册和登录页面进行局部切换的逻辑、用账号密码登录的相关逻辑、用手机号和验证码登录的相关逻辑、获取验证