Python Web 企业级项目开发教程(Django 版)(第2版)课件 第6章 身份验证系统_第1页
Python Web 企业级项目开发教程(Django 版)(第2版)课件 第6章 身份验证系统_第2页
Python Web 企业级项目开发教程(Django 版)(第2版)课件 第6章 身份验证系统_第3页
Python Web 企业级项目开发教程(Django 版)(第2版)课件 第6章 身份验证系统_第4页
Python Web 企业级项目开发教程(Django 版)(第2版)课件 第6章 身份验证系统_第5页
已阅读5页,还剩124页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章身份验证系统《PythonWeb企业级项目开发教程(Django版)(第2版)》学习目标/Target掌握User对象,能够通过User对象的create_user()和create_superuser()

方法创建普通用户和超级用户掌握权限管理,能够对用户和组的权限进行管理熟悉如何自定义权限,能够归纳自定义权限的两种方式掌握默认权限,能够检测和查看当前用户具有哪些权限掌握用户登录与退出,能够实现用户登录与退出功能学习目标/Target掌握限制用户访问的方式,能够使用3种方式实现限制用户访问掌握自定义用户模型的方式,能够根据需求自定义用户模型掌握Cookie的基本操作,能够对Cookie执行设置、读取和删除操作熟悉模板中身份验证的方式,能够说明如何在模板中进行身份验证掌握Session的基本操作,能够对Session执行写入和读取操作章节概述/Summary身份验证系统是Django框架内置的一种身份验证和权限控制机制,它提供了一系列的类和方法,用于实现用户身份验证、注册、登录、注销、密码重置等功能。此外,Django身份验证系统还支持多种权限控制方式,可以根据用户的角色或组别进行权限控制。本章将对Django身份验证系统相关的知识进行介绍。目录/Contents010203User对象权限与权限管理Web请求认证目录/Contents040506模板身份验证自定义用户模型状态保持User对象6.1

先定一个小目标!掌握User对象,能够通过User对象的create_user()和create_superuser()方法创建普通用户和超级用户6.1User对象参数说明username表示用户名,长度在150字符以内,可以由字母、数字和“_@+.-”字符组成password表示用户密码,长度无限制、可以由任意字符组成email表示用户的邮箱地址first_name表示用户的名last_name表示用户的姓在Django中User对象是用来管理应用程序的用户身份验证和授权的核心部分。Django提供了内置的User模型,用于处理用户账户的创建、认证和管理。User对象通过User模型类创建,该类中内置了很多与用户信息相关字段,如用户名、密码、邮件,其中常用字段如下。6.1User对象参数说明email表示用户的电子邮件is_superuser布尔值,如果值为True表示超级用户is_active布尔值,如果值为True表示用户已激活is_staff布尔值,如果值为True表示该用户可以访问管理站点date_joined用户的创建日期时间,默认设置为当前日期时间last_login用户上次登录的日期时间在Django中User对象是用来管理应用程序的用户身份验证和授权的核心部分。Django提供了内置的User模型,用于处理用户账户的创建、认证和管理。User对象通过User模型类创建,该类中内置了很多与用户信息相关字段,如用户名、密码、邮件,其中常用字段如下。6.1User对象User类中为了方便开发人员创建普通用户和超级用户,提供了两个方法:create_user()和create_superuser()。注意,在使用这些方法之前,需要确保已经生成了数据表,即已经执行迁移文件命令。下面分别演示如何使用这两个方法创建普通用户和超级用户。6.1User对象1.使用create_user()方法创建普通用户create_user()方法的语法格式如下。username:用户的用户名。这是创建用户时必须提供的参数,用于唯一标识用户。email:用户的电子邮件地址。这是可选的参数,但通常也是创建用户时要提供的信息之一。password:用户的密码。用户在创建时需要设置密码。extra_fields:其他额外的参数以关键字参数的形式传入,可以包含任意额外的用户信息,比如年龄、性别等。create_user(username,email=None,password=None,**extra_fields)语法格式6.1User对象为了便于后续演示,先创建chapter06项目,然后执行迁移文件命令,最后在该项目的DjangoShell中使用create_user()方法创建用户,示例如下。>>>fromdjango.contrib.auth.modelsimportUser#导入User类>>>#创建普通用户>>>ordinary_user=User.objects.create_user('zhangsan','zhangsan@’,'zhangsan123')>>>ordinary_user.save()6.1User对象2.使用create_superuser()方法创建超级用户create_superuser()方法的语法格式如下。create_user(username,email=None,password=None,**extra_fields)语法格式create_superuser()函数与create_user()函数的各个参数的含义与用法相似,此处不再赘述。6.1User对象在DjangoShell中使用创建超级用户,示例如下。>>>fromdjango.contrib.auth.modelsimportUser#导入User类>>>#创建超级用户>>>super_user=User.objects.create_superuser('lisi','lisi@','lisi123')>>>super_user.save()6.1User对象默认情况下,通过User类创建的用户默认保存在数据表auth_user中。auth_user表中的数据如图所示。6.1User对象超级用户lisi的is_superuser与is_staff字段为1,普通用户zhangsan的is_superuser与is_staff字段为0,这正因create_user()和create_superuser()的区别所致,即通过create_user()方法创建的用户会将其is_staff字段与is_superuser字段设置为False;通过create_superuser()方法创建的用户会将其is_staff字段与is_superuser字段为True。6.1User对象使用User对象的set_password()方法可以修改用户的密码。例如,修改超级用户lisi的密码,具体代码如下。>>>fromdjango.contrib.auth.modelsimportUser>>>u=User.objects.get(username='lisi')>>>u.set_password('lisi4321') #设置新密码>>>u.save() #保存新密码6.1User对象Django中可以使用authenticate()函数来验证用户,该函数通过参数username和password分别接收用户名和密码。如果用户名和密码正确,验证成功,返回一个User对象;否则后端引发PermissionDenied错误,并返回None。6.1User对象接下来,通过一个用户登录的示例演示authenticate()函数的使用,具体步骤如下。(1)在chapter06项目中新建goods应用,在该应用的views.py文件中定义LoginView类视图。在LoginView类视图中,使用authenticate()函数来验证超级用户lisi是否存在。若lisi存在,则返回响应登录的用户名,否则返回响应“登录失败”。示例代码如右。fromdjango.httpimportHttpResponsefromdjango.contrib.authimportauthenticatefromdjango.viewsimportViewclassLoginView(View):defget(self,request):returnrender(request,'login.html')defpost(self,request):username=request.POST.get("username")password=request.POST.get('password')user=authenticate(username=username,password=password)ifuserisnotNone:returnHttpResponse(f"用户:{user}")returnHttpResponse("登录失败")示例演示6.1User对象(2)在chapter06项目中新建templates文件夹。在templates文件夹中新建模板文件login.html,在该文件中定义登录表单。示例代码如下。<formmethod="post">{%csrf_token%}<labelfor="username">用户名:</label><inputtype="text"id="username"name="username"required><br><labelfor="password">密码:</label><inputtype="password"id="password"name="password"required><br><inputtype="submit"value="登录"></form>示例演示6.1User对象(3)在chapter06项目的settings.py文件的TEMPLATES选项中配置模板文件访问路径,示例如下。'DIRS':[os.path.join(BASE_DIR,'templates')](4)在chapter06项目的urls.py文件定义匹配类视图LoginView的URL模式,示例如下。fromgoodsimportviewsurlpatterns=[path('login/',views.LoginView.as_view())]示例演示6.1User对象运行开发服务器,在浏览器地址栏中访问:8000/login/,用户名对应的文本框输入“lisi”,密码对应的文本框输入“lisi4321”,然后单击登录按钮,如图所示。示例演示6.1User对象权限与权限管理6.2

先定一个小目标!掌握默认权限,能够检测和查看当前用户具有哪些权限6.2.1默认权限在Django中,权限是用于控制用户对特定资源或操作的访问权限的机制。权限是建立在用户和用户组之上的,可以根据用户的角色或组织结构来划分不同的权限。权限管理则是指对用户或用户组进行授权和限制其对资源或操作的访问权限的过程。它是一种安全机制,用于确保只有经过授权的用户能够执行特定的操作或访问特定的资源。6.2.1默认权限Django内置了一个简单的权限系统,若INSTALLED_APPS中安装了django.contrib.auth应用后,定义新的模型并执行生成迁移文件和执行迁移文件命令,该系统会为每个已安装Django模型创建增(add)、删(delete)、改(change)、查(view)这四种权限,这些权限信息会保存到auth_permission数据表中。6.2.1默认权限例如,在goods应用的models.py文件中定义模型类,示例如下。fromdjango.dbimportmodelsclassAddress(models.Model):name=models.CharField(max_length=11,verbose_name='用户名')phone=models.CharField(max_length=11,unique=True,verbose_name='手机号')state=models.CharField(max_length=100,verbose_name='省')city=models.CharField(max_length=100,verbose_name='市')street=models.CharField(max_length=100,verbose_name='街道')6.2.1默认权限模型类定义完成之后,在chapter06项目的settings.py文件的INSTALLED_APPS选项中安装goods应用,然后再执行生成迁移文件和执行迁移文件命令。此时,在数据表auth_permission可查看新增的权限,如图所示。6.2.1默认权限auth_permission表中各字段说明如下。id:权限的唯一标识符,是自动生成的主键。name:权限描述说明。content_type_id:数据表django_content_type的外键,django_content_type表用于记录表和应用的对应关系,它有app_label和model两个字段,分别表示应用名和模型类名。codename:权限,形式为“权限_类名”。6.2.1默认权限通过User对象的has_perm()方法和get_all_permissions()方法可以检测当前用户具有哪些权限。下面分别介绍这两个方法。1.has_perm()方法has_perm()方法用于检测用户是否具有某种权限,其语法格式如下。has_perm('应用名.权限名_模型名')语法格式当返回值为True时,表明该用户具有某种权限。6.2.1默认权限例如,在DjangoShell中检测用户lisi是否具有增加、删除、修改、查看地址信息的权限,示例代码如下。>>>fromdjango.contrib.auth.modelsimportUser>>>user=User.objects.get(username='lisi')>>>user.has_perm('goods.add_address') #检测用户lisi是否有添加权限True>>>user.has_perm('goods.change_address') #检测用户lisi是否有修改权限True>>>user.has_perm('goods.delete_address') #检测用户lisi是否有删除权限True>>>user.has_perm('goods.view_address') #检测用户lisi是否有查看权限True6.2.1默认权限2.get_all_permissions()方法get_all_permissions()方法用于查看用户的所有权限,其返回值是当前用户权限的集合。例如,在DjangoShell中查看创建的超级用户lisi所包含的权限,具体代码如下。>>>fromdjango.contrib.auth.modelsimportUser>>>user=User.objects.get(username='lisi')>>>user.get_all_permissions()#查看用户john的所有权限{'admin.add_logentry','sessions.view_session','auth.view_group','auth.view_permission','sessions.add_session','goods.view_address','goods.delete_address','auth.add_permission','contenttypes.delete_contenttype','contenttypes.view_contenttype','auth.delete_permission','auth.add_group',...}6.2.1默认权限

先定一个小目标!掌握权限管理,能够对用户和组的权限进行管理6.2.2权限管理Django的权限管理是指通过在项目中配置和设置权限规则,控制用户对资源的访问和操作。Django提供了强大且灵活的权限管理系统,允许开发者对不同用户或用户组分配不同的权限,并在视图或模板中进行权限检查。下面分为用户权限管理、组权限管理、用户加入组三部分进行介绍。1.用户权限管理Django内置的权限模型类为Permission,利用该类可以创建与管理权限;Django内置的用户模型类User继承了抽象类AbstractUser。AbstractUser又同时继承AbstractBaseUser类和PermissionsMixin类,其中PermissionsMixin类通过user_permissions字段与权限类Permission模型建立多对多关系。综上所述,User类与Permission类存在多对多关系,通过关系字段user_permissions属性可对用户的权限进行管理。6.2.2权限管理若想对用户的权限进行管理,则可以通过User类的user_permissions属性调用set()、add()、remove()和clear()方法进行管理,这四个方法的示例代码如下。fromdjango.contrib.auth.modelsimportUseruser=User.objects.get(username='用户名')user.user_permissions.set([permission_list]) #添加权限列表user.user_permissions.add(permission,...) #添加权限user.user_permissions.remove(permission,...) #移除权限user.user_permissions.clear() #清空权限上述示例中,set()方法表示为用户添加权限列表,在set()方法中需要传入包含多个权限的列表;add()方法表示为用户添加指定的权限;remove()方法表示从用户的权限集合中移除一个或多个权限;clear()方法表示清空用户的所有权限。6.2.2权限管理权限模型类Permission中共包含3个字段,分别为name、content_type和codename。通过Permission模型管理器的get()方法和codename字段可获取具体的权限对象。例如,获取当前管理员“lisi”的删除用户权限和添加用户权限,示例代码如下。>>>fromdjango.contrib.auth.modelsimportPermission>>>#获取删除用户权限>>>del_perm=Permission.objects.get(codename="delete_user")>>>#获取添加用户权限>>>add_perm=Permission.objects.get(codename="add_user")6.2.2权限管理下面通过add()、remove()和clear()方法对超级用户“lisi”和普通用户zhangsan的权限进行管理,示例代码如下。>>>fromdjango.contrib.auth.modelsimportUser>>>user_lisi=User.objecte.get(username="lisi")>>>user_zs=User.objecte.get(username="zhangsan")>>>user_zs.user_userpermissions.add(del_perm)#为用户zhangsan添加del_perm权限>>>user.user_userpermissions.remove(add_perm)#移除超级用户lisi的add_perm权限>>>user_zs.user_userpermissions.clear()#清空用户zhangsan的所有权限以上示例代码首先导入User类与Permission类,然后通过Permission类的get()方法分别获取“delete_user”和“add_user”权限,之后根据用户名称获取用户对象user,最后使用add()、remove()、clear()方法对权限进行操作。6.2.2权限管理2.组权限管理若想对用户的组权限进行管理,则可以通过Group类的permissions属性调用set()、add()、remove()和clear()方法进行管理,这四个方法的示例代码如下。fromdjango.contrib.auth.modelsimportGroup#导入Group类group=Group.objects.create(name="组名") #创建组group.permissions.set([permission_list]) #添加组权限列表group.permissions.add(permission,...) #添加组权限group.permissions.remove(permission,...) #移除组权限group.permissions.clear() #清空组权限上述示例中,set()方法表示为组添加权限列表,在set()方法中需要传入权限列表;add()方法表示为组添加指定的权限;remove()方法表示从组的权限集合中移除一个或多个权限;clear()方法表示清空组的所有权限。6.2.2权限管理下面通过add()、remove()和clear()方法对“Python”组的权限进行管理。首先使用create()方法创建组,示例代码如下。>>>fromdjango.contrib.auth.modelsimportGroup>>>group=Group.objects.create(name="Python")#创建Python组>>>group.save()然后为Python组分配权限,示例代码如下。>>>fromdjango.contrib.auth.modelsimportPermission>>>add_perm=Permission.objects.get(codename="add_user")>>>remove_perm=Permission.objects.get(codename="view_user")>>>group.permissions.add(add_perm)#添加add_user权限>>>group.permissions.remove(remove_perm)#移除view_user权限>>>group.permissions.clear()#清空组权限6.2.2权限管理3.用户加入与退出组如果想让多个用户拥有相同的权限,那么可以将这些用户分配到同一个组中,通过设置组权限来管理用户权限。若将用户加入到某个已存在的组中,该用户会被赋予该组的所有权限;从组中移除用户,可同时回收用户从该组获取的权限。通过User类的groups属性调用set()、add()、remove()和clear()方法提供了管理组内用户的方法,这些方法的语法格式如下。user.groups.set([group_list]) #将用户添加到列表中所有的组user.groups.add(group,group,...)#将用户添加到多个组user.groups.remove(group,group,...)#将用户从指定的组中删除user.groups.clear()#用户退出所有组6.2.2权限管理将管理员用户lisi添加到组Python中、从Python组中移除、让用户lisi退出所有组,示例代码如下。>>>fromdjango.contrib.auth.modelsimportUser,Group>>>user=User.objects.get(username="lisi")>>>group=Group.objects.get(name="Python")>>>user.groups.add(group)#将用户添加到Python组>>>user.groups.remove("Python")#从Python组移除用户>>>user.groups.clear()#用户lisi退出所有组6.2.2权限管理

先定一个小目标!熟悉如何自定义权限,能够归纳自定义权限的两种方式6.2.3自定义权限在Django中,我们可以自定义权限来满足特定的应用程序需求。自定义权限可以用于对特定的操作或资源进行访问控制,以确保只有具有相应权限的用户才能执行这些操作或访问这些资源。下面介绍两种方式实现自定义权限。第一种方式在定义模型类时通过在Meta类指定permissions属性定义自定义权限;第二种方式使用ContentType模型类动态创建和管理权限。6.2.3自定义权限1.通过在Meta类指定permissions属性Meta类中permissions属性用于定义Django模型的权限,该属性是一个包含多个元组的列表,每个元组表示一个权限。每个权限元组包含两个元素:权限代号(codename)和权限名称(name),权限代号是用于在代码中引用权限的标识符,而权限名称则是显示给用户的描述性名称。定义Django模型的权限的语法格式如下。classAddress(models.Model): #定义的模型类

passclassMeta:#添加自定义权限

permissions=(('权限代号','权限名称'))6.2.3自定义权限例如,在模型类Address中自定义导出权限export_info,示例代码如下。classAddress(models.Model):name=models.CharField(max_length=11,verbose_name='用户名')

phone=models.CharField(max_length=11,unique=True,verbose_name='手机号')

state=models.CharField(max_length=20,verbose_name='省')

city=models.CharField(max_length=20,verbose_name='市')

street=models.CharField(max_length=100,verbose_name='街道')

def__str__(self):returnf"{},{self.phone},{self.state},{self.city},{self.street}"classMeta:permissions=[('export_info','exportaddressinfo')]#自定义权限自定义权限定义完成之后,还需要执行生成迁移文件和执行迁移文件命令,这样自定义权限便会添加到auth_permission数据表中。6.2.3自定义权限自定义权限定义完成后,我们可以判断用户是否具有这个权限,如果用户具有这个权限,那么执行相应操作;如果用户不具有这个权限,那么进行相应提示。例如,检测用户是否具有export_info权限,如果具有,那么将数据库中的地址信息保存到csv文件中。数据库中地址信息如图所示。6.2.3自定义权限实现根据用户权限是否保存地址信息,具体步骤如下。(1)在goods应用的views.py文件中定义类视图DownloadView,在该类视图的get()方法中渲染模板文件download.html;在post()方法中验证用户对象,并判断该用户对象是否具有指定权限,示例代码如右。importcsvfrom.modelsimportAddressfromdjango.viewsimportViewclassDownloadView(View):defget(self,request):returnrender(request,'download.html')defpost(self,request):username=request.POST.get("username")password=request.POST.get('password')user=authenticate(username=username,password=password)ifuserisnotNone:...returnHttpResponse("登录失败")示例演示6.2.3自定义权限(2)在模板文件download.html中需要定义一个登录表单,示例代码如下。<formmethod="post">{%csrf_token%}<labelfor="username">用户名:</label><inputtype="text"id="username"name="username"required><br><labelfor="password">密码:</label><inputtype="password"id="password"name="password"required><br><inputtype="submit"value="下载"></form>示例演示6.2.3自定义权限(3)在chapter06项目的urls.py文件中为类试图DownloadView配置URL模式,示例代码如下。path('download/',views.DownloadView.as_view())示例演示6.2.3自定义权限(4)运行开发服务器,在浏览器地址栏中访问:8000/download/,在用户名文本框中输入“lisi”,在密码文本框输入“lisi4321”,如果登录的用户具有export_info权限,那么会提示下载保存地址信息的address.csv文件,如果登录的用户不具有export_info权限,那么提示“用户权限不足”。用户具有export_info权限,保存的地址信息如图所示。示例演示6.2.3自定义权限示例演示用户不具有export_info权限,响应“用户权限不足”,如图所示。6.2.3自定义权限2.使用ContentType类自定义权限ContentType类为Django中的模型类,在数据库中对应的数据表为django_content_type,该数据表包括id字段、表示应用名的app_label字段和表示模型名的model字段,用于记录当前Django项目中所有模型与应用的对应关系。可通过ContentType类提供的get_for_model()方法获取模型类或模型实例,通过Permission类中的create()方法为获取的模型或模型实例添加权限。6.2.3自定义权限例如,在goods应用的views.py文件中通过ContentType类为模型类Address定义export_info权限,示例代码如下。fromdjango.httpimportHttpResponsefrom.modelsimportAddressfromdjango.contrib.auth.modelsimportPermissionfromdjango.contrib.contenttypes.modelsimportContentTypedefcreate_perm(request):content_type=ContentType.objects.get_for_model(Address)permission=Permission.objects.create(codename='export_info_demo',name='exportaddressinfodemo',content_type=content_type,)permission.save()returnHttpResponse('添加权限成功')6.2.3自定义权限然后在chapter06项目的urls.py文件中定义匹配视图函数create_perm()的URL模式,示例代码如下。path('create-perm/',views.create_perm)运行开发服务器,在浏览器的地址栏中访问:8000/create-perm/,若权限添加成功,则响应“添加权限成功”。6.2.3自定义权限Web请求认证6.3

先定一个小目标!掌握用户登录与退出,能够实现用户登录与退出功能6.3.1用户登录与退出在Django中,Web请求的认证是通过会话(Session)和中间件(Middleware)实现,会话(Session)是指在特定时间段内,用户与系统或应用程序之间的交互和通信过程;中间件是处理请求和响应的一种机制。请求认证系统与请求对象紧密结合,在每个请求上提供了request.user属性和request.auser()异步方法,用于获取当前用户和用户信息;如果用户未登录,request.user获取的结果将是一个AnonymousUser实例,用于表示匿名用户。6.3.1用户登录与退出用户登录与退出是网站中最基本的功能之一,用户登录确保只有经过身份验证的用户才能访问受限制的页面或执行特定的操作。通过登录,应用程序可以验证用户的身份,以确定其是否具有足够的权限来执行请求的操作。这有助于保护敏感信息,确保只有授权的用户才能访问;用户退出操作将结束其当前的会话。通过退出,用户的会话将被终止,应用程序将不再与用户保持连接,这有助于防止其他人访问用户的账户和个人数据。6.3.1用户登录与退出1.用户登录用户登录实质上是将一个已验证的用户附加到当前会话中,在Django中可以使用login()函数实现用户登录,该函数的作用如下。(1)验证用户的凭据:login()函数会接收用户提供的用户名和密码,并将其与存储在数据库或其他数据源中的用户数据进行验证,以确保用户身份的有效性和正确性。(2)标记用户为已登录状态:验证成功后,login()函数会将用户对象标记为已登录状态,这将使用户能够访问需要身份验证的功能和页面。(3)处理会话管理:为了跟踪用户的登录状态和操作,login()函数会创建和管理会话数据。它会将用户ID等相关信息存储在会话中,并在后续请求中使用该ID来识别用户。此外,login()函数还可以实现会话的过期和清除,以提高安全性和性能。6.3.1用户登录与退出login()函数语法格式如下。request:必选参数,表示当前请求的HttpRequest对象。它包含了与当前请求相关的所有信息,如请求头、请求方法、URL等。user:必选参数,表示要登录的用户对象。通常是User模型的实例,该模型是Django内置的身份验证系统提供的默认用户模型。User模型包含了用户的认证信息,如用户名、密码等。backend:可选参数,一个字符串,表示要使用的认证后端。如果未提供,则使用默认的认证后端。login(request,user,backend=None)语法格式6.3.1用户登录与退出6.3.1用户登录与退出在使用login()函数时,我们不仅要关注用户的身份验证和权限管理,更要保障用户的隐私和数据安全。我们可以通过加密用户密码、采用多因素认证等方式,提升用户账户的安全性,防范各类网络攻击和信息泄露风险。同时,我们也应该积极宣传网络安全知识,提升用户的安全意识,共同构建一个安全的网络环境。接下来,通过一个示例演示使用login()函数实现用户登录,具体步骤如下。(1)在goods应用的views.py文件中定义类视图SigninView,在该类视图中使用login()函数登录用户,具体代码如右。fromdjango.contrib.authimportauthenticatefromdjango.contrib.authimportloginclassSigninView(View):defget(self,request):returnrender(request,'signin.html')defpost(self,request):username=request.POST['username']password=request.POST['password']user=authenticate(request,username=username, password=password)ifuserisnotNone:login(request,user) #用户登录

returnrender(request,'info.html',{'user':user})else:returnHttpResponse(f'用户名或密码错误')示例演示6.3.1用户登录与退出(2)在templates文件夹中创建模板文件signin.html,在该模板文件中实现登录表单,示例代码如下。<formmethod="post">{%csrf_token%}<labelfor="username">用户名:</label><inputtype="text"id="username"name="username"required><br><labelfor="password">密码:</label><inputtype="password"id="password"name="password"required><br><inputtype="submit"value="登录"></form>示例演示6.3.1用户登录与退出(3)在templates文件夹中创建模板文件info.html,在该模板文件中实现登录成功的提示信息以及退出按钮,示例代码如下。<p>登录成功,{{user}}您好!</p><formmethod="get">{%csrf_token%}<inputtype="submit"value="退出"></form>示例演示6.3.1用户登录与退出(4)在chapter06项目的urls.py文件中定义匹配类视图SigninView的URL模式,示例代码如下。path('signin/',views.SigninView.as_view(),name='signin'),运行开发服务器,在浏览器地址栏中访问:8000/signin/,用户名对应的文本框输入“lisi”,密码对应的文本框输入“lisi4321”,然后单击登录按钮,登录成功页面如图所示。示例演示6.3.1用户登录与退出2.用户退出Django提供了logout()函数实现用户退出功能,该函数接收HttpRequest对象,没有返回值。调用logout()函数退出登录后,当前会话中存储的登录数据会被清除。在用户退出登录时,我们需要确保用户的身份信息得到妥善处理,避免出现信息残留和泄露的问题。我们可以通过及时清除用户的登录状态、销毁相关的会话信息等方式,有效地保护用户的隐私和数据安全。此外,我们也应该倡导用户自主管理个人信息的意识,鼓励他们定期修改密码、清理浏览记录等,保障个人信息的安全和隐私。6.3.1用户登录与退出例如,使用logout()函数退出登录的用户“lisi”,具体步骤如下。(1)在goods应用的views.py文件中定义类视图SignoutView,在该类视图的get()方法中使用logou()函数退出登录的用户,退出成功后,页面跳转到登录页面,示例代码如下。fromdjango.contrib.authimportlogoutclassSignoutView(View):"""退出登录"""defget(self,request):logout(request)#重定向到登录页面

returnredirect(reverse('signin'))6.3.1用户登录与退出(2)在templates文件夹中修改模板文件info.html,在该模板文件中通过url标签指定单击退出按钮时发送的请求,示例代码如下。<p>登录成功,{{user}}您好!</p><formmethod="get"action="{%url'logout'%}">{%csrf_token%}<inputtype="submit"value="退出"></form>6.3.1用户登录与退出(3)在chapter06项目的urls.py文件中定义匹配类视图SigninView的URL模式,示例代码如下。path('logout/',views.SignoutView.as_view(),name='logout'),运行开发服务器,在浏览器地址栏中先访问:8000/signin/,并使用用户“lisi”进行登录,然后单击“退出”按钮,页面跳转至登录页面,如图所示。6.3.1用户登录与退出

先定一个小目标!掌握限制用户访问的方式,能够使用3种方式实现限制用户访问6.3.2限制用户访问限制用户访问是指在网站或应用程序中,通过一些机制或规则,限制特定用户或用户组对某些功能、页面或资源的访问权限。限制用户访问的目的是确保只有经过身份验证的用户才能执行特定的操作或访问特定的页面,例如登录成功的用户才能访问用户中心页面。这可以提高网站或应用程序的安全性,并防止未经授权的用户访问敏感信息或执行敏感操作。Django中使用request.user.is_authenticated属性、装饰器login_required和LoginRequiredMixin类三种方式限制用户访问。6.3.2限制用户访问1.request.user.is_authenticated属性request.user.is_authenticated属性用来判断用户是否通过验证,该属性会返回一个布尔值,如果布尔值为True,那么表示当前登录用户对象提供了有效的用户名和密码;如果布尔值为False,那么表示当前登录用户对象提供了错误的用户名和密码。如果输入错误的用户名和密码,那么页面将重定向到登录页面,登录页面对应的URL地址通常在settings.py文件中通过配置项LOGIN_URL进行指定,例如指定登录页面的URL地址为/login/,示例代码如下。LOGIN_URL='/login/'#登录页面的URL6.3.2限制用户访问虽然通过配置项LOGIN_URL可以指定重定向到登录页面,但如果希望登录成功之后,自动重定向到原始请求页面,那么可以在URL中通过参数next进行指定,具体格式如下所示。redirect(f"{settings.LOGIN_URL}?next={request.path}")上述格式中,redirect()函数用于生成重定向响应;settings.LOGIN_URL用于获取登录页面的URL地址;“?”表示查询字符串分隔符;参数next用于重定向回原始请求;request.path表示获取当前请求路径。6.3.2限制用户访问通过一个案例演示通过request.user.is_authenticated属性限制用户访问,如果用户登录成功,那么重定向到用户中心页面;如果用户没有登录成功,那么重定向到登录页面。6.3.2限制用户访问(1)在goods应用的views.py文件中定义类视图UserLogin,在该类视图的get()方法中渲染模板文件signin.html;在post()方法中先获取用户输入的用户名和密码,然后使用authenticate()函数对用户信息进行验证,如果验证失败响应“用户名或密码错误”;如果验证通过使用is_authenticated属性判断用户是否能够访问用户中心页面;若允许,则跳转用户中心页面,示例代码如右。classUserLogin(View):defget(self,request):returnrender(request,'signin.html')defpost(self,request):username=request.POST['username']password=request.POST['password']user=authenticate(request,username=username,password=password)ifuserisnotNone:login(request,user)ifrequest.user.is_authenticated:returnredirect(reverse('userinfo'))else:returnHttpResponse(f'用户名或密码错误')示例演示6.3.2限制用户访问(2)在goods应用的views.py文件中定义类视图UserInfo,在该类视图的get()方法中使用is_authenticated属性判断用户是否具有访问用户中心页面的权限,如果具有,那么渲染用户中心页面;如果不具有;那么重定向到登录页面,示例代码如下。fromdjango.confimportsettingsclassUserInfo(View):defget(self,request):ifrequest.user.is_authenticated:returnrender(request,'userinfo.html',{'user':request.user})else:returnredirect(f"{settings.LOGIN_URL}?next={request.path}")示例演示6.3.2限制用户访问(3)在chapter06项目的urls.py文件中定义匹配类视图UserLogin和UserInfo的URL,示例如下。path('user-login/',views.UserLogin.as_view()),path('info/',views.UserInfo.as_view(),name='userinfo'),(4)在templates文件夹中新建模板文件userinfo.html,在该模板文件中展示当前登录的用户,示例代码如下。<body><p>登录成功,{{user}}您好!</p></body>示例演示6.3.2限制用户访问运行开发服务器,在浏览器地址栏中访问:8000/info/,因为用户未登录直接访问用户中心页面,所以页面会重定向到登录页面,并在URL地址中指定原始请求地址,登录页面具体如图所示。示例演示6.3.2限制用户访问如果输入正确的用户名和密码,那么userinfo.html页面会展示当前登录的用户,用户中心页面具体如图所示。示例演示6.3.2限制用户访问2.装饰器login_required装饰器login_required用于在视图层面限制用户访问,它有两个参数:login_url和redirect_field_name。其中,login_url表示重定向地址,默认为None;redirect_field_name表示重定向字段名称,默认值为"next",该字段保存了用户成功验证后浏览器应跳转的地址。6.3.2限制用户访问例如,用户直接访问用户中心页面,如果用户没有登录,那么重定向到登录页面;如果用户登录成功,那么重定向到用户中心页面,示例代码如下。fromdjango.confimportsettingsfromdjango.contrib.auth.decoratorsimportlogin_required@login_required(login_url=settings.LOGIN_URL)defuserinfo(request):ifrequest.method=='GET':ifrequest.user.is_authenticated:returnrender(request,'userinfo.html',{'user':request.user})6.3.2限制用户访问3.LoginRequiredMixin类使用LoginRequiredMixin类同样可在视图层面限制用户访问,该类的具体用法为:从django.contrib.auth.mixins模块中引入LoginRequiredMixin,定义继承LoginRequiredMixin类的类视图,在定义的类视图中通过类属性login_url指定登录页面的URL地址,示例代码如下。fromdjango.contrib.auth.mixinsimportLoginRequiredMixinclassUserInfo(LoginRequiredMixin,View):login_url=settings.LOGIN_URLdefget(self,request):ifrequest.user.is_authenticated:returnrender(request,'userinfo.html',{'user':request.user})需要注意,LoginRequiredMixin类必须位于类视图基类列表的最左侧。6.3.2限制用户访问模板身份验证6.46.4模板身份验证

先定一个小目标!熟悉模板中身份验证的方式,能够说明如何在模板中进行身份验证在模板中进行身份验证,可以根据用户的身份状态或权限级别来个性化展示内容、控制访问权限、提供个性化导航以及控制表单显示与处理,从而提升用户体验并确保系统的安全性。在Django中,通过RequestContext类将当前登录用户对象和该用户的权限传递到模板文件中,此时在模板中分别使用变量{{user}}和{{perms}}表示当前登录用户对象和该用户的权限信息。注意,RequestContext类不需要开发人员手动实例化,这是因为使用render()函数渲染模板文件时会自动实例化RequestContext对象。6.4模板身份验证1.变量{{user}}通过案例演示在模板文件中使用变量{{user}},在模板文件中对{{user}}变量进行验证,若验证通过则在页面中显示用户名,否则提示用户去登录。6.4模板身份验证(1)在goods应用的views.py文件定义类视图VerifyUser,并分别实现get()方法和post()方法,在get()方法渲染登录页面,在post()方法中获取用户输入的用户名和密码,并使用login()函数进行登录,登录成功后渲染模板文件verify.html,示例代码如右。classVerifyUser(View):defget(self,request):returnrender(request,'login.html')defpost(self,request):username=request.POST['username']password=request.POST['password']user=authenticate(request,username=username,password=password)ifuserisnotNone:login(request,user)ifrequest.user.is_authenticated:returnrender(request,'verify.html')else:returnHttpResponse(f'用户名或密码错误')示例演示6.4模板身份验证(2)在templates文件夹中新建模板文件verify.html中,在该模板文件中通过is_authenticated属性对{{user}}变量进行验证,若验证通过则在页面中显示用户名,否则提示用户去登录,示例代码如下。示例演示<formmethod="post">{%csrf_token%}{%ifuser.is_authenticated%}

欢迎您:<em>{{user.username}}</em>{%else%}<p>用户未登录,请先登录</p>{%endif%}</form>6.4模板身份验证(3)在chapter06项目的urls.py文件中定义类视图VerifyUser配置URL,示例代码如下。示例演示fromdjango.urlsimportpathurlpatterns=[path('admin/',admin.site.urls),path('verify/',views.VerifyUser.as_view()),]6.4模板身份验证运行开发服务器,在浏览器地址栏中输入:8000/verify/,若用户登录成功,此时页面会显示当前登录的用户名。如图所示。示例演示6.4模板身份验证无缝衔接单元测试2.变量{{perms}}{{perms}}变量还可以检测当前登录用户是否拥有某个应用的具体权限。例如,检测当前登录用户是否拥有具有goods应用my_permission权限,在模板文件verify.html使用perms属性验证用户是否具有my_permission权限,示例代码如下。<formmethod="post">{%csrf_token%}{%ifperms.goods.my_permission%}<p>用户:{{user}}具有下载地址信息权限</p>{%else%}<p>用户:{{user}}不具有下载地址信息权限</p>{%endif%}</form>6.4模板身份验证运行开发服务器,在浏览器地址栏中输入:8000/verify/,若用户登录成功,此时页面会显示当前登录的用户具有下载地址信息的权限。如图所示。6.4模板身份验证自定义用户模型6.56.5自定义用户模型

先定一个小目标!掌握自定义用户模型的方式,能够根据需求自定义用户模型尽管Django内置的用户模型类中包含许多通用字段,但在实际开发项目时可能需要使用额外的用户字段,此时可以编写自定义代码,对内置用户模型类进行拓展。自定义用户模型类需要继承django.contrib.auth.models模块中的抽象类AbstractUser,并在用户模型类中自定义额外的字段。6.5自定义用户模型例如,在goods应用的models.py文件中通过继承AbstractUser自定义用户模型User,示例代码如下。fromdjango.contrib.auth.modelsimportAbstractUserclassUser(AbstractUser):name=models.CharField(max_length=20,verbose_name='姓名')mobile=models.CharField(max_length=11,verbose_name='手机号码')recv_address=models.TextField(blank=False,verbose_name='收货地址')classMeta:db_table='users'def__str__(self):return6.5自定义用户模型User模型定义完成之后,修改settings.py中的AUTH_USER_MODEL选项,使其指向自定义用户

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论