Flask 拦截器

news/2025/4/1 2:43:40/

登录实现后,有很多页面还没有进行设置登录要求,即使没有登录也可以到页面中来,当页面多了以后,每个页面都进行设置又非常繁琐,所以这里用到了 Flask 拦截器

相关资料源码来自编程浪子的Flask点餐小程序系统

web/interceptors/AuthInterceptor.py

import refrom application import app
from flask import request, redirect, gfrom common.libs.LogService import LogService
from common.libs.user.UserService import UserService
from common.models.User import User
from common.libs.UrlManager import UrlManager@app.before_request
def before_request():ignore_urls = app.config['IGNORE_URLS']ignore_check_login_urls = app.config['IGNORE_CHECK_LOGIN_URLS']path = request.pathuser_info = check_login()# 如果是静态文件就不要查询用户信息了pattern = re.compile('%s' % "|".join(ignore_check_login_urls))if pattern.match(path):returnif '/api' in path:returnuser_info = check_login()g.current_user = Noneif user_info:g.current_user = user_info# 加入日志LogService.addAccessLog()pattern = re.compile('%s' % "|".join(ignore_urls))if pattern.match(path):returnif not user_info:return redirect( UrlManager.buildUrl("/user/login"))return'''
判断用户是否已经登录
'''def check_login():cookies = request.cookiesauth_cookie = cookies[app.configp['AUTH_COOKIE_NAME']] if app.config['AUTH_COOKIE_NAME'] in cookies else Noneif auth_cookie is None:return False
# 0 是授权码,  1是uidauth_info = auth_cookie.split('#')if len(auth_info) !=2:return Falsetry:user_info = User.query.filter_by(uid=auth_info[1]).first()except Exception:return Falseif user_info is None:return Falseif auth_info[0] != UserService.geneAuthCode(user_info):return Falseif user_info.status != 1:return Falsereturn user_info

Config/base_setting.py设置无需拦截器拦截的url,防止login都被拦截了,出现死循环。

## 过滤url
IGNORE_URLS = ["^/user/login"
]IGNORE_CHECK_LOGIN_URLS =["^/static""^/favicon.ico"
]

        这段代码是一个Python的Flask应用程序中的配置项。其中定义了两个列表变量IGNORE_URLSIGNORE_CHECK_LOGIN_URLS,用于配置需要忽略的URL路径。

IGNORE_URLS列表中的正则表达式定义了一些URL路径,这些路径在进行登录检查时会被忽略。例如,“^/user/login"表示以”/user/login"开头的路径将被忽略。

IGNORE_CHECK_LOGIN_URLS列表中的正则表达式定义了一些URL路径,这些路径在进行登录检查时也会被忽略。例如,“^/static"表示以”/static"开头的路径将被忽略。

        这些配置项的作用是在进行登录检查时,排除一些特定的URL路径,使其不受登录检查的限制。

问题1: ^的作用是什么?

正则表达式中,^符号的作用是匹配字符串的开头位置。在给定的代码中,^被用于定义忽略的URL模式。具体来说,IGNORE_URLS列表中的正则表达式会匹配以"/user/login"开头的URL,而IGNORE_CHECK_LOGIN_URLS列表中的正则表达式会匹配以"/static""/favicon.ico"开头的URL。这样,当用户访问这些URL时,系统会忽略对用户登录状态的检查

问题2:pattern = re.compile('%s' % "|".join(ignore_check_login_urls))

这段代码的作用是将ignore_check_login_urls列表中的元素用竖线|连接起来,并将结果作为参数传递给re.compile()函数,生成一个 正则表达式模式对象 。这个模式对象可以用于匹配path字符串 是否 符合 其中 任意一个元素的模式。

例如,如果ignore_check_login_urls列表中有两个元素['/login', '/register'],那么生成的正则表达式模式对象就是re.compile('/login|/register')。这个模式对象可以用于判断path字符串是否匹配/login/register

问题3: 下段代码是什么意思?

auth_cookie = cookies[app.config['AUTH_COOKIE_NAME']] if app.config['AUTH_COOKIE_NAME'] in cookies else None

这段代码是用来获取名为auth_cookie的cookie的值。它首先检查cookies字典中是否存在键为app.config['AUTH_COOKIE_NAME']的项,如果存在,则将其值赋给auth_cookie变量;如果不存在,则将auth_cookie赋值为None

这段代码的作用是判断是否存在名为app.config['AUTH_COOKIE_NAME']的cookie,并将其值赋给auth_cookie变量。如果存在该cookie,则auth_cookie变量将保存该cookie的值;如果不存在该cookie,则auth_cookie变量将为None


def check_login():cookies = request.cookiesauth_cookie = cookies[app.configp['AUTH_COOKIE_NAME']] if app.config['AUTH_COOKIE_NAME'] in cookies else Noneif auth_cookie is None:return False
# 0 是授权码,  1是uidauth_info = auth_cookie.split('#')

问题4: 该段代码中auth_info是啥?

auth_info是一个列表,其中包含两个元素。第一个元素是授权码(auth_code),第二个元素是用户ID(uid)。

在这段代码中,首先检查名为AUTH_COOKIE_NAME的cookie是否存在于cookies字典中。如果存在,将其赋值给auth_cookie变量;否则,将auth_cookie设置为None

接下来,检查auth_cookie是否为None。如果是,表示未找到授权cookie,返回False

最后,使用split('#')方法将auth_cookie按照#分隔符拆分成两个元素,并将结果赋值给auth_info变量。

说实话到这我已经迷糊了,cookie是已经之前在web/controllers/user/User.py中定义好的

response.set_cookie( app.config['AUTH_COOKIE_NAME'], '%s#%s' % (UserService.geneAuthCode(user_info), user_info.uid), 60 * 60 * 24 * 120)   # 保存120填

这段代码将会设置一个名为app.config['AUTH_COOKIE_NAME']的cookie,其值为'%s#%s' % (UserService.geneAuthCode(user_info), user_info.uid),并且过期时间为120天

common/libs/user/UserService.py

class UserService():@staticmethoddef geneAuthCode(user_info = None):   #user_info 是哪来的? 用函数时带的 geneAuthoCode(user_info)m = hashlib.md5()str = "%s-%s-%s-%s" % (user_info.uid, user_info.login_name, user_info.login_pwd, user_info.login_salt)m.update(str.encode("utf-8"))return m.hexdigest()

这段代码是一个静态方法,属于UserService类。它用于 生成用户的身份验证码。下面是对代码的详细解析:

  1. 首先,导入了hashlib模块,用于进行哈希操作。
  2. 然后,定义了一个静态方法geneAuthCode,该方法接受一个参数user_info,用于传入用户信息。
  3. 在方法内部,创建了一个hashlib.md5()对象,用于进行MD5哈希操作。
  4. 接下来,根据用户信息的不同属性,构建了一个字符串str,其中包含了用户的uidlogin_namelogin_pwdlogin_salt
  5. 使用m.update()方法,将字符串str进行UTF-8编码后更新到MD5对象中。
  6. 最后,使用m.hexdigest()方法,获取MD5对象的哈希值,并将其作为身份验证码返回。

这段代码的作用是根据用户的信息生成一个唯一的身份验证码,用于 用户身份验证 或 其他安全相关的操作。

可以按照以下步骤使用UserService类中的geneAuthCode方法生成用户认证码

  1. 导入UserService类:
    from UserService import UserService
  2. 创建UserService对象:
    user_service = UserService()
  3. 调用geneAuthCode方法生成用户认证码:
    user_info = # 获取用户信息
    auth_code = user_service.geneAuthCode(user_info)

    这样,你就可以使用  UserService类  中的  geneAuthCode方法  生成 用户认证码了。


问题5: 回归总结一下,cookie就是两个值,一个是用户认证码,一个是uid。 这两个值是什么样的呢?

response.set_cookie函数用于设置Cookie。app.config['AUTH_COOKIE_NAME']是Cookie的名称,'%s#%s' % (UserService.geneAuthCode(user_info), user_info.uid)是Cookie的值, 60 * 60 * 24 * 120是Cookie的过期时间(单位为秒)。

这个例子中,Cookie的值由两部分组成,用#符号分隔。第一部分是用户验证码,由UserService.geneAuthCode(user_info)生成。第二部分是用户的uid

以下是一个示例,展示如何生成 用户验证码uid

user_info = {'uid': 123,'username': 'example_user'
}auth_code = UserService.geneAuthCode(user_info)
uid = user_info['uid']print("用户验证码:", auth_code)
print("用户uid:", uid)

输出结果:

用户验证码: abcdefg
用户uid: 123

也就是说cookie是这样一个值  abcdefg#123


问题6: auth_info = auth_cookie.split('#') 中 auth_info是啥值 请给个案例

auth_info  是通过将auth_cookie字符串使用 "#" 进行分割后得到的一个  列表 。具体的值取决于auth_cookie的内容。下面是一个示例:

auth_cookie = 'abcd1234#12345'
auth_info = auth_cookie.split('#')
print(auth_info)

输出结果为:

['abcd1234', '12345']

auth_info是一个由授权码用户ID组成的列表。授权码在列表的索引0处,用户ID在列表的索引1处。


问题7: Exception是什么,有什么作用?

Exception是Python中的一个内置类,用于处理异常情况。在try-except语句中,当try块中的代码发生异常时,程序会跳转到对应的except块中执行异常处理代码。Exception类是所有异常类的基类,可以捕获任何类型的异常。通过捕获Exception类,可以处理所有可能发生的异常情况,确保程序的稳定性和可靠性。

Exception类的作用是提供了一种统一的异常处理机制,使得程序可以在出现异常时进行适当的处理,避免程序崩溃或产生不可预料的错误。通过捕获和处理异常,可以对异常情况进行适当的处理,例如输出错误信息、记录日志、回滚事务等。

在给定的代码中,try-except语句中的except块捕获了Exception异常,并返回False。这样做的目的是在发生异常时,返回一个特定的值,以便在调用该代码的地方进行进一步的处理或判断。

问题8: return False是怎么的一个值,在浏览器中会怎样显示?

return False是一个返回值,表示函数执行到这一步时返回了False。在浏览器中,如果这段代码是在后端服务器上执行的,那么浏览器不会直接显示返回值。相反,它会根据后端服务器的逻辑来处理返回值。可能会返回一个错误页面或者其他相应的信息。

如果你想在浏览器中显示返回值,你可以使用前端技术(如JavaScript)来处理后端返回的数据,并将其显示在浏览器上。这样你就可以根据返回值来决定在浏览器中显示什么内容。

文章来源:https://blog.csdn.net/xinzhengLUCK/article/details/135146286
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/news/1283660.html

相关文章

【开源】基于JAVA的智能教学资源库系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程档案表3.2.2 课程资源表3.2.3 课程作业表3.2.4 课程评价表 四、系统展示五、核心代…

软件测试/测试开发丨Pytest测试用例生命周期管理-Fixture

1、Fixture 用法 Fixture 特点及优势 1、命令灵活:对于 setup,teardown,可以不起这两个名字2、数据共享:在 conftest.py 配置⾥写⽅法可以实现数据共享,不需要 import 导⼊。可以跨⽂件共享3、scope 的层次及…

java浅拷贝BeanUtils.copyProperties引发的RPC异常 | 京东物流技术团队

背景 近期参与了一个攻坚项目,前期因为其他流程原因,测试时间已经耽搁了好几天了,本以为已经解决了卡点,后续流程应该顺顺利利的,没想到 人在地铁上,bug从咚咚来~ 没有任何修改的服务接口,抛出…

代码审计必要性探讨

1、背景 为了保证代码的质量,需要一系列的流程来进行保证: 今天要探讨的是代码审计的必要性。 2、代码审计 代码审计的做法多种多样,我理解必须解决以下问题 ,才可能有效: 核心:审计的本质是对比&#…

CentOS 5/6/7 基于开源项目制作openssh 9.6p1 rpm包—— 筑梦之路

背景介绍 开源项目地址:https://github.com/boypt/openssh-rpms.git 该项目主要支持了centos 5 、6、7版本,针对使用了比较老的操作系统进行openssh安全加固,还是不错的项目,使用简单、一件制作,欢迎大家去支持作者。…

火山引擎边缘云获“2023边缘计算年度领航企业”及“最佳CDN创新企业”等多项荣誉

近日,在边缘计算社区主办的第八届全球边缘计算大会与亚太CDN产业联盟主办的第十三届亚太内容分发大会暨CDN峰会上,火山引擎边缘云凭借面向未来发展的技术创新、丰富的产品与解决方案以及多样场景下的最佳实践案例,从众多申报企业中脱颖而出&a…

<JavaEE> TCP 的通信机制(三) -- 滑动窗口

目录 TCP的通信机制的核心特性 四、滑动窗口 1)什么是滑动窗口? 2)滑动窗口的作用是什么? 3)批量传输出现丢包如何处理? 1> 接收端ACK丢包 2> 发送端数据包丢包 4)适用性 TCP的通…

springboot实现数据库故障自动切换

实现数据库故障自动切换的方案可以借助数据库连接池和心跳检测机制。下面是一种常见的实现方式: 配置文件准备: 在 application.properties 或 application.yml 文件中设置主备数据库的配置,包括连接信息和其他相关配置。 连接池配置&#x…