Django框架下的用户鉴权机制分析与研究
2023-11-30张小梅何菊佘侃侃戴彩艳
张小梅 何菊 佘侃侃 戴彩艳
基金项目:国家自然科学基金青年基金项目;项目名称:名老中医甲状腺疾病辨治规律挖掘策略及方法研究;项目编号:No.82004498。南京中医药大学校自然科学基金青年基金项目;项目名称:基于衰减系数的动态蛋白质网络建模及研究;项目编号:No.NZY61906100。
作者简介:张小梅(2000— ),女,贵州毕节人,本科生;研究方向:计算机网络与应用。
*通信作者:何菊(1979— ),女,江苏常州人,讲师,博士研究生;研究方向:中医药人工智能与大数据分析。
摘要:用户鉴权是Web应用中保障数据安全性的重要组成部分,主要作用是确认Web应用程序中每个用户的身份,以便限制用户对资源的访问和操作。文章从用户鉴权的生命周期、主要技术原理切入,结合Django框架初级的用户鉴权机制即中间件、装饰器的解读,由浅入深地分析了用户鉴权机制的重要性以及技术实现的多样性,让读者从原理上了解基于用户鉴权实现的网络安全设计常识,并且能从Django的封装过程中更好地体会用户鉴权逻辑的设计。
关键词:用户鉴权;Django框架;身份验证
中图分类号:TN915.04中图分类号 文献标志码:A文献标志码
0 引言
用户鉴权是指验证用户身份以限制用户对资源的正确访问与操作,是应用程序中保护用户隐私的重要组成部分。通常,用户鉴权机制包括通过特殊的方式验证用户身份以及设计权限级别来限制用户访问或操作两部分,实现系统的安全性和数据的保密性。本文从用户鉴权的生命周期引入,分析实现用户鉴权的步骤原理;再深入介绍主流的鉴权机制,简单说明不同机制的优缺点;最后以Django框架为例,分析用户认证的两种封装思路——中间件和装饰器,完整地解读用户鉴权是什么以及多样的实现思路。
1 用户鉴权的生命周期
基于用户登录才能使用完整服务的网站具有完整的用户鉴权机制,系统产生的数据需要从用户身份的维度进行维护和管理,用户鉴权需要经过5个步骤。
1.1 用户提交身份验证凭证
网站的注册登录页面是用户鉴权机制的开始,常见的凭证方式有用户名密码验证、第三方认证(如登录某Web系统时选择使用Google账号登录)和单点登录(用户在一个Web应用中登录后,可以自动登录到另一个Web应用中)。
1.2 服务器验证凭证的有效性
通俗来说,这个阶段是对用户提交的信息进行校验。比对用户名、密码是否与数据库内存储的一致,或者通过外部接口实现的第三方认证、单点登录信息是否有效。如果校验不通过,将返回错误提示信息给前端,如果验证通过,进入用户机制验证的下一个阶段。
1.3 服务器校验成功
用户身份验证成功,服务器将会生成一个唯一的标识符代表用户身份,并根据用户身份生成一个用户会话来存储用户身份凭证,其中唯一标识符会作为响应的一部分传到客户端保存。基于不同的使用场景,可以分为cookie、session和token 3种机制。
1.4 用户访问受保护的资源
用户登录之后向程序发起的每一次请求,都会自动带上保存在客户端的唯一标识符,如果访问的资源是受保护的,Web应用会主动检查唯一标识符的有效性,即会话的有效性,如果会话已超时,就重定位到登录页面。
1.5 服务器注销用户凭证和会话
当用户完成操作或注销登录后,服务器会注销用户凭证和会话。
2 用户认证机制
Web应用程序是基于HTTP网络传输协议实现的,而HTTP本身具有无连接的特点,即每次请求和响应之间是独立的,为实现用户认证,需要根据使用场景使用额外的技术来实现和维持登录状态[1]。
2.1 用户认证之cookie
cookie的原理是将用户身份验证信息以小型的文本文件方式保存在客户端浏览器中,每次用户向Web服务器发起请求时,浏览器会自动将cookie附加到HTTP请求头中发送给Web服务器,服务器通过解析cookie来获取用户身份验证信息[2]。cookie的优点是易于实现和管理,但由于用户可以在本地修改和操纵cookie,因此必须谨慎使用。此外,cookie还有大小限制,可以存储的用户信息较少。
2.2 用户认证之session
session是为了解决cookie存储在客户端容易被篡改或伪造而升级的一种机制,通过session对象的方式将用户身份信息存储在服务器,而session对象包含的唯一id则作为cookie的一部分传递到客户端浏览器保存。当用户再次访问网站时,就通过session id查找对应的session对象,检查是否过期。相较于cookie而言,session机制将用户鉴权信息保存在服务器端,因此比cookie更加安全。
2.3 用户认证之token
token是用户登录成功后,服务器为用户创建的基于json格式存储用户信息的认证机制。token以cookies或缓存的方式存在于客户端,与cookie相比,token以包含签名的方式防止伪造[3]。token主要應用在微服务、移动应用、对外API场景中,属于高级的用户认证机制。
2.4 Django的session机制
在Django中使用的用户认证机制是session机制。默认情况下Django将session对象存储在数据库中,也可以将session存储在缓存中或文件中。常见的网站首页未登录时右上角显示“登录”按钮,已登录时则显示当前登录的用户名这一场景,用Django实现的步骤如下。
(1)在setting.py文件中设置session的存储方式:session_engine值(默认为Django.contrib.sessions.backends.db,即数据库存储)。
(2)设置session信息:在视图中通过request.session[session_key]
=session_value的格式设置以键值形式存储的session信息。
(3)使用session信息:在模板中使用{{ request.session.session_key }}来获取session的key;在视图函数中通过request.session.get(session_key)的方式获取session的key。
3 Django的访问控制机制
Django的Access Control提供了多种访问控制方式,包括中间件、装饰器等多种机制,以适应不同的鉴权场景。
3.1 中间件
客户端与浏览器的交互在Django机制下的过程是:客户端发起的请求在到达视图函数处理前会先经过Django的一个个中间件,每个中间件有机会观察或修改请求,并将他们传递给下一个中间件,通过了所有中间件的验证放行,请求才能到达视图函数,否则会直接返回客户端。服务器的响应也是通过层层中间件的验证,进行必要的加工处理后才到达客户端。
中间件其实就是一个类,继承了MiddlewareMixin类,类内定义了一些函数,如process_request()、process_response()等方法。请求到达Django程序时会依次执行中间件的process_request方法,直到最后一个中间件传递给view处理函数。完成view处理函数的执行后,将执行的结果response返回给最后一个中间件的process_response方法,直到第一个中间件处理完process_response方法并返回response[2]。
关于用户是否登录的校验可以封装在一个中间件的process_request方法里,通过request.session.get()方法获取身份校验信息,对于不需要登录就能访问的网页,如注册、登录页放行(process_request函数没有返回值或返回为空),对于其他页面,如果没有登录就强制重定向到登录页面。
让中间件生效需要在settings.py的文件的MIDDLEWARE字段注册中间件。中间件按照注册的顺序从上往下执行,自定义的中间件注册时根据使用场景合理考虑位置。
3.2 装饰器
装饰器(Decorator)本质上是一个Python函数或类,用来给其他函数或类添加额外功能而不用修改类或函数本身。下面是一个示例,用于检查用户是否已登录并进行相应的处理。
def login_required(view_func):
def wrapped_view(request, *args, **kwargs):
if not request.user.is_authenticated: # 判断状态是否为登录
return redirect('login') # 重定向到登录页面
return view_func(request, *args, **kwargs)
return wrapped_view
装饰器的实现方式是函数对象、闭包加@语法糖。Python的函数可以作为返回值传递给其他函数,这是使用装饰器的基础。闭包就是函数的嵌套,内部函数可以访问外部函数的变量、参数和其他内部函数,最后返回内部函数的引用[4]。@语法糖用于简化装饰器的调用方式,实现方式是在被装饰函数上方添加一个@符号,紧接着是装饰器函数的名字。
上述代码定义了一个装饰器login_required,它接收一个视图函数view_func作为参数,并返回一个新的包裹了原视图函数的函数wrapped_view。在wrapped_view中,检查用户是否已经通过身份验证(即登录状态),如果没有通过验证,则将用户重定向到登录页面。
使用装饰器来保护需要登录验证的视图函数,如下例:
@login_required
def my_view(request):
# 用户必须登录后才能访问的视图函数
# 执行相应的处理逻辑
…
当使用@语法糖调用装饰器时,被装饰的函数作为装饰器函数的参数传递给装饰器函数,并将装饰器函数的返回值赋值给原始函数的引用。在上述代码中,通过在视图函数my_view上使用@login_required装饰器,实现该视图函数只有在用户已登录的情况下才能被访问,否则用户将被重定向到登录页面。
Python的装饰器还可以形成链式调用,一个或多个装饰器可以依次对函数进行包装和修改。
4 结语
用户鉴权机制是网络安全的重要组成部分,Django的用户鉴权机制提供了一个强大而灵活的工具来实现用户认证和权限管理。除了本文提到的session機制和中间件、装饰器实现的访问控制,Django还提供了强大的权限系统组件如 Permission、model Permission等更进阶的封装。通过深入研究和理解这些机制,可以构建出安全可靠的应用程序,并为用户提供良好的访问体验。希望本文的研究能对读者在使用和扩展Django的鉴权机制上,提供有益的指导和启示。
参考文献
[1]刘翠芬.浅谈基于HTTP方式的认证[J].职教论坛,2003(20):57.
[2]趙路.Django框架CSRF防御实现机制浅析[J].网络安全技术与应用,2021(4):18-19.
[3]林琳.详细了解Cookie Session Token[J].计算机与网络,2019(22):38-40.
[4]李德水.Python类装饰器装饰方法通用编码模型分析[J].电子设计工程,2020(13):41-44,49.
(编辑 沈 强)
Analysis and research on user authentication mechanism under Django framework
Zhang Xiaomei, He Ju*, She Kankan, Dai Caiyan
(College of Artificial Intelligence and Information Technology,Nanjing University of Chinese Medicine, Nanjing 210023, China)
Abstract: User authentication is an important component of ensuring data security in web applications. Its main function is to confirm the identity of each user in the web application, in order to restrict user access and operation of resources. This article starts with the lifecycle and main technical principles of user authentication, and combines the interpretation of the basic user authentication mechanisms, namely middleware and decorator, in the Django framework. It analyzes the importance of user authentication mechanisms and the diversity of technical implementations from simple to deep, allowing readers to understand network security design knowledge based on user authentication from a theoretical perspective, and to better understand the design of user authentication logic from the encapsulation process of Django.
Key words: user authentication; Django framework; authentication