Django之Auth认证模块

Django之Auth认证模块在平常我们使用 Django 开发的过程中都需要设计 Web 用户系统其中包含 用户注册 登录 修改密码 登录认证 注销等功能

大家好,欢迎来到IT知识分享网。

一、简介

在平常我们使用Django开发的过程中都需要设计Web用户系统其中包含:用户注册、登录、修改密码、登录认证、注销等功能。而这些都是由我们手动将数据拿到数据库表中一一匹对,太过于麻烦。那么我们今天使用到的Auth模块可以完美解决这个问题,提升使用Django的开发效率


二、Auth模块是什么

Auth是Django自带的用户认证模块

Django作为一个完美主义者的终极框架,当然也会想到开发者的这些痛点,它内置了强大的用户认证系统:auth,它默认使用auth_user表来存储用户数据(也就是第一次迁移数据库时Django创建的表之一)

三、Auth模块常用方法

auth模块常用的属性和方法:

属性或方法 解释
auth.authenticate 判断用户名和密码
is_authenticated 判断用户是否登录
request.user 获取当前登录用户
login_required 校验用户是否登录装饰器
check_password 校验密码是否正确
set_password 修改密码
auth.logout(request) 退出登录
create_user() 创建用户和加密密码
AbstractUser 基于auth扩写

我们可以通过一下来导入Auth模块:

 from django.contrib import auth 

create_user() 创建普通用户

auth提供的一个创建新用户的方法,需要提供必要参数(username,password)等。

导入方式:

 from django.contrib.auth.models import User 

我们创建的用户默认会被添加到auth_user表中,首先我们得有一个注册页面,便于能够快速起到效果,这里就没有校验二次密码了,有兴趣就自行添加即可。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">注册页面</h1> <hr> <form action="" method="post"> { 
   % csrf_token %} <p>username: <input type="text" name="username" class="form-control"> </p> <p>password: <input type="password" name="password" class="form-control"> </p> <input type="submit" class="btn btn-block btn-success" value="注册"> </form> </div> </div> </div> </body> </html> 

视图函数:

from django.contrib import auth from django.contrib.auth.models import User def register(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 校验用户名是否已存在 # 这个方法必须要传递用户名和密码,单个不行会获取出None # obj = auth.authenticate(request,username=username,password=password) obj = User.objects.filter(username=username,password=password) if obj: return HttpResponse('用户名已存在') # 注册用户 # User.objects.create(username=username,password=password) #不能自己创建,因为密码加密无法实现 else: User.objects.create_user(username=username,password=password) # create_user方法会自动对密码加密 return HttpResponse('注册成功!') return render(request,'register.html') 

那么此时我们就实现了用户的账号注册功能。在auth_user表中就可以看到我们刚才注册的用户,并且Django帮助我们存储的过程中将密码进行了加密处理。

在这里插入图片描述


authenticate() 用户认证

提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username、password两个关键字参数。

导入方式:

 from django.contrib.auth import authenticate 

如果认证成功(用户名和密码正确有效),便会返回一个User对象。

authenticate()会在该User对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。

登录Web

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">登录页面</h1> <hr> <form action="" method="post"> { 
   % csrf_token %} <p>username: <input type="text" name="username" class="form-control"> </p> <p>password: <input type="password" name="password" class="form-control"> </p> <input type="submit" class="btn btn-block btn-success" value="登录"> </form> </div> </div> </div> </body> </html> 

视图函数:

 def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 校验用户是否存在 自己是无法比对,因为密码存入其中加密了,所以需要用到auth模块提供的方法才可以 obj = auth.authenticate(request,username=username,password=password) # 用户名和密码正确之后返回的是数据对象,反之返回None # print(obj.password, obj.username) if obj: return HttpResponse('登录成功!') else: return HttpResponse('用户名或密码错误!') return render(request,'login.html') 

此时,我们便已经完成验证用户账号和密码是否正确的一个功能,此时再浏览器输入正确的用户名与密码,就会显示登录成功!

究其本质还是Django把我们输入的内容拿到了auth_user表中对比,匹对成功了返回一个User对象给我们,只不过这些步骤我们只需要调用一个API就可以是实现。


auth.login(HttpResponse,user)登录状态保持

如果现在有一个home页面需要登录之后才能访问,那么我们就需要再用户登录之后制作一个登录标识保存在Session中,那么访问home页面校验一下Session即可判断出来。这是我们之前的操作,需要手动设置Session,在手动验证Session是否存在。

login函数接收一个HttpResponse对象,以及一个经过认证的User对象。

该函数实现一个用户登录的功能,它本质上会在后端为该用户生产相关session数据。

该函数需要再用户认证以后使用,因为它的第二个参数需要传入一个User对象。

 from django.contrib.auth import authenticate def login(request): print(request.user.is_authenticated) # True表示存在此用户, print(request.user) # 没有登录显示:AnonymousUser匿名用户 登录显示登录的用户对象数据 ''' 用户登录成功之后执行Auth.login 该方法返回当前登录用户对象 admin 用户没有登录成功没有执行Auth.login 该方法返回匿名用户对象 AnonymousUser ''' if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 校验用户是否存在 自己是无法比对,因为密码存入其中加密了,所以需要用到auth模块提供的方法才可以 obj = auth.authenticate(request,username=username,password=password) # 用户名和密码正确之后返回的是数据对象,反之返回None print(obj.password, obj.username) if obj: # 用户登录成功后(返回给客户端一个登录凭证、字符串、令牌) auth.login(request, obj) # 自动操作django_session表,返回一个凭证给客户端 ''' 当执行上述的操作之后,我们就可以通过reqeust.user直接获取到当前登录的用户对象数据 ''' return HttpResponse('登录成功!') else: return HttpResponse('用户名或密码错误!') return render(request,'login.html') 

此时我们还需配合下面的Auth方法一起使用才能看到效果


is_authenticated 登录认证判断

用来判断当前请求是否通过了登录认证。其主要还是判断请求内是否包含用户登录后的Session

定义一个home页面,只有检测到用户登录后才能访问,否则重定向到登录页面

登录验证Web

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> { 
   % if request.user.is_authenticated %} # 判断当前请求是否为登录状态 <h1>{ 
   { 
    request.user.username}}</h1> { 
   % else %} <a href="/auth_register/">注册</a> <a href="/auth_login/">登录</a> { 
   % endif %} </body> </html> 

视图函数:

 def home(request): return render(request,'home.html') 

ps:reqeust.use具备很多方法,一些其它的常用方法在有需求的情况下在做了解

到这里我们已经实现了登录认证,登录状态保持的一个效果,后端也可以识别当前是否为登录状态,并且知道当前登录的用户是那个。


auth.loginout(reqeust)退出登录

该函数接受一个HttpResponse对象,无返回值。

当调用该函数时,当前请求的Session信息会被全部清除。即使没有登录,使用该函数也不会报错。

后端清空了当前用户保存的Session信息,也可以理解为没有登录状态了,下次访问某些页面需要重新登录

 def login_out(request): auth.logout(request) return HttpResponse('已注销用户!') 

当是这种退出登录,不管什么登录状态的都清除掉session这样不算合格,所以我们需要先校验是否登录。


login_required() 登录认证装饰器

在上面我们是通过Web页面里面使用了request.user.is_authenticated校验是否登录的

现在我们为了更加简单实现,auth给我们提供了一个装饰器工具,用来快捷的给某个视图添加登录校验

 @login_required def login_out(request): auth.logout(request) return HttpResponse('已注销用户!') 

若用户没有登录,则会跳转到Django默认的登录URL/accounts/login/并且URL会额外显示:?next=/跳转之前的路径/

如果需要自定义登录的URL,有两种方式:

  1. 需要再settings.py文件中通过LOGIN_URL进行修改。
 LOGIN_URL = '/auth_login/' #这里配置成你的项目登录页面的路由 
  1. 手动指定:用户没有登录时重定向到登录页面
 @login_required(login_url='/auth_login/') def indexs(request): # if request.user.is_authenticated: # return HttpResponse('只有登录的用户可见') # else: # return redirect('/auth_login/') return HttpResponse('只有登录的用户可见') 

如果我们想要在登录之后立马跳转到被重定向之前的页面,使用方式一,因为它会保留定义之前的URL:

 if obj: # 用户登录成功后(返回给客户端一个登录凭证、字符串、令牌) auth.login(request, obj) # 自动操作django_session表,返回一个凭证给客户端 urls = reqeust.GET.get('next') if not urls: urls = '/index/' # 如果没有获取到,就默认登录后跳转到首页 return redirect(urls) 

check_password(password) 检查密码

auth提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。

密码正确返回True,否则返回False。但必须在登录之后并且保存了登录Session才能使用

使用方法:

 user = request.user.check_password('密码') 

set_password(password)修改密码

auth 提供的一个修改密码的方法,接受要设置的新密码作为参数。

注意:设置完一定要调用用户对象的save方法!!! 通常在check_password校验之后使用

我们使用这两个来实现修改密码的功能

web:set_html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">修改密码页面</h1> <hr> <form action="" method="post"> { 
   % csrf_token %} <p>username: <input type="text" name="username" class="form-control" value="{ 
   { request.user.username }}" disabled> </p> <p>oldpassword: <input type="password" name="old_pwd" class="form-control"> </p> <p>newpassword: <input type="password" name="new_pwd" class="form-control"> </p> <p>Confirm_password <input type="password" name="confirm_pwd" class="form-control"> </p> <input type="submit" class="btn btn-block btn-success" value="提交"> </form> </div> </div> </div> </body> </html> 

视图函数:

@login_required def set_pwd(request): if request.method == 'POST': user = request.user # 获取当前用户对象 old_pwd = request.POST.get('old_pwd') # 获取用户输入的旧密码 new_pwd = request.POST.get('new_pwd') # 获取用户输入的新密码 confirm_pwd = request.POST.get('confirm_pwd') # 二次确认新密码 if not new_pwd == confirm_pwd: return HttpResponse('两次密码不一致') # 判断原密码是否正确 res = request.user.check_password(old_pwd) if not res: return HttpResponse('原密码错误!') else: #修改密码 request.user.set_password(new_pwd) request.user.save() # 将修改后的数据保存在auth_user表中 auth.login(request,user) # 因为用户信息发生变动,需要修改用户的session数据才能保持登录状态 return HttpResponse('修改成功!') return render(request,'set.html') 

用户删除

如果是管理员的话,可以删除其他用户,如果是普通用户的话,只能删除自己

管理员删除需要前端传递一个用户id到后端才能进行删除;需要路由定义分组来接收并传递给视图函数

 # 管理员删除用户 @login_required def auth_delete(request,id): auth.logout(request) user = User.objects.filter(pk=id) user.delete() return HttpResponse('.....') 路由层配置urls.py re_path('auth_delete/(\dt)/', views.auth_delete,name='auth_delete'), 

普通用户,仅只能删除自身

 @login_required def auth_delete(request): request.user.delete() return HttpResponse('.....') 

注意:如果连接的是sqlite数据库,很可能会删除失效,建议换成MySQL数据库


创建超级用户

超级用户首先具备登录admin后端的能力,其次可以在里面删除其它用户;

超级用户的创建方式有两种:

  1. 通过:Python3 manage.py createsuperuser命令,根据提示输入用户名、邮箱(可输入空)、密码、二次密码等
  2. 通过Auth组件创建;与创建普通用户区别不大,只是获得权限不同

第一种方式:

django自带一个admin路由,但是需要我们提供管理员账户和密码,如果想要使用admin后台管理,需要先创建表,然后创建管理员账户。

在这里插入图片描述
直接执行数据类迁移命令即可产生默认的auth_user表,该表就是admin后台管理默认的认证表
在这里插入图片描述

​ 在控制台输入命令python38 manage.py createsuperuser

在执行创建管理员命令后,运行环境会提示我们输入用户名,邮箱(选填),密码等信息,依次输入即可。这样我们的auth_user表中就会添加一条数据,这条数据就是管理员用户信息。


第二种方式:
web:super_register.html 建立超级用户

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1 class="text-center">超级用户创建</h1> <form action="" method="post"> { 
   % csrf_token %} <p>用户名:<input type="text" name="username" class="form-control"></p> <p>邮箱:<input type="email" name="email" class="form-control"></p> <p>密码:<input type="password" name="password" class="form-control"></p> <p><input type="submit" value="提交" class="form-control btn-warning"></p> </form> </div> </div> </body> </html> 

视图函数

 # 创建超级管理员用户 def auth_super_register(request): if request.method == 'POST': username = request.POST.get('username') email =request.POST.get('email') password = request.POST.get('password') User.objects.create_superuser(username=username,email=email,password=password) return HttpResponse('超级用户创建成功!') return render(request,'super_register.html') 

创建完成以后我们就可以通过刚刚创建的账号和密码登录到Django的admin后台管理界面了

在这里插入图片描述


四、拓展Auth_user表

在原来的基础authmok的功能,并且又想扩展auth_user表的字段

思路1:一对一字段关联(不推荐)

 from django.contrib.auth.models import User class OtherUser(models.Model): user = models.OneToOneField(to=User) """ 将User表与OtherUser的字段一一对应,操作起来很麻烦""" 

思路2:替换auth_user表(推荐)

 步骤1:模型层编写模型类继承AbstractUser from django.contrib.auth.models import AbstractUser class UserInfo(AbstactUser): # 继承原管理表格 # 填写AbstactUser表中没有的字段 phone=models.BinIntegerField() # 可以随意添加 desc=models.TextField() 步骤2:一定要配置文件中声明替换关系 AUTH_USER_MODEL='app01.UserInfo' # 告诉orm 使用app01 下的UserInfo表替换原先的auth_user表 ps:替换还有一个前提,就是数据库迁移命令没有执行过(auth相关表没有创建),用全新的库 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/153713.html

(0)
上一篇 2025-03-02 15:33
下一篇 2025-03-02 15:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信