• Django 用户认证


    Django内置了丰富的用户认证体系。使用用户、用户组和权限完成。

    Auth模块

    内置的Django权限管理模块,在项目中文件settings.py中的INSTALLED_APPS引入django.contrib.auth模块

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app1',  # 自己创建的应用
        'app3',
        # 'app2',
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    因此引入auth如下:

    form django.contrib import auth
    在这里插入图片描述
    数据库迁移会生成如上所示的一些数据表

    • auth_user 用户信息
    • auth_group 组信息
    • auth_permission 权限信息
    • auth_user_group 用户和组的关系
    • auth_group_permissions 组和权限的关系
    • auth_user_user_permissions 用户和权限关系

    对应的模型引入如下:
    Django.contrib.auth.models.

    • User 用户
    • Group 组
    • Permission 权限

    Auth常见方法

    方法说明
    authenticate(username, password)用户验证,成功返回User
    login(HttpRequest, user)用户登陆
    is_authenticated()当前用户是否认证
    logout(request)注销会话
    create_user()创建新用户
    set_password(password)修改密码
    check_password(password)检查密码正确与否

    用户管理

    用户注册

    建立一个页面注册用户
    user = User.objects.create_user(**d) 这里 * * 表示参数按照元组简析传递。
    views.py

    def user_reg(request):
        if request.method == "GET":
            return render(request, 'app1/user_reg.html')
        if request.method == "POST":
            uname = request.POST.get("username", "")
            pwd = request.POST.get("password", "")
            if User.objects.filter(username=uname):
                info = '用户已经存在'
            else:
                d = dict(username=uname, password=pwd, email='111@111.com',
                         is_staff=1, is_active=1, is_superuser=1)
                user = User.objects.create_user(**d)
                info = '注册成功,请登录'
    
            return render(request, 'app1/user_reg.html', {"info": info})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    页面

    {% load static %}
    <form action="" method="post">
      {% csrf_token %}
      <div class="input-group mb-3">
        <input
          type="text"
          class="form-control"
          name="username"
          placeholder="用户名"
        />
      div>
    
      <div class="input-group mb-3">
        <input type="email" class="form-control" name="email" placeholder="邮箱" />
      div>
    
      <div class="input-group mb-3">
        <input
          type="password"
          class="form-control"
          name="password"
          placeholder="密码"
        />
      div>
    
      <div class="input-group mb-3">
        <input
          type="password"
          class="form-control"
          name="re-password"
          placeholder="重复密码"
        />
      div>
      <div class="row">
        <div class="col-8">
          <label for="agreeTerms">{{ info }}label>
        div>
        <div class="col-4">
          <button type="submit" class="btn btn-primary btn-block">注册button>
        div>
      div>
    form>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    在这里插入图片描述

    用户登陆

    authenticate方法验证用户,返回用户
    login登陆用户
    根据不同的信息,返回对应的信息

    from django.contrib.auth import authenticate, login
    
    def user_login(request):
        if request.method == "GET":
            return render(request, 'app1/login.html')
        if request.method == "POST":
            uname = request.POST.get("username", "")
            pwd = request.POST.get("password", "")
            if User.objects.filter(username=uname):
                user = authenticate(username=uname, password=pwd)
                if user:
                    if user.is_active:
                        login(request, user)
                        info = '登陆成功'
                    else:
                        info = '用户还没激活'
                else:
                    info = '账户密码不对,请重新输入'
            else:
                info = '用户账户不对,请查询'
    
            return render(request, 'app1/login.html', {"info": info})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    login.html

    {% load static %} nihao lvgui
    <form action="" method="post">
      {% csrf_token %}
      <div class="input-group mb-3">
        <input
          type="text"
          class="form-control"
          name="username"
          placeholder="用户名"
        />
        <div class="input-group-append">
          <div class="input-group-text">
            <span class="fas fa-user">span>
          div>
        div>
      div>
    
      <div class="input-group mb-3">
        <input
          type="password"
          class="form-control"
          name="password"
          placeholder="密码"
        />
        <div class="input-group-append">
          <div class="input-group-text">
            <span class="fas fa-lock">span>
          div>
        div>
      div>
    
      <div class="row">
        <div class="col-8">
          <label for="agreeTerms">{{ info }}label>
        div>
        <div class="col-4">
          <button type="submit" class="btn btn-primary btn-block">登陆button>
        div>
      div>
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    用户扩展

    在对应的应用中创建MyUser继承AbstractUser,这里扩展了三个字段。

    from django.contrib.auth.models import AbstractUser
    class MyUser(AbstractUser):
        photo = models.CharField('用户头像', max_length=50)
        weChat = models.CharField('微信', max_length=30)
        level = models.CharField('用户等级', max_length=1)
    
        def __str__(self):
            return self.username
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    然后在setting中配置对应的模型,app1.MyUser是对应的model,也是生成的数据库名。

    AUTH_USER_MODEL = ‘app1.MyUser’

    然后扩展数据库,如果这里是半中央去扩展用户模型,需要删除migrations下除了init的其余python文件,最后将数据库中相关的表也删除。

    python manage.py migrations
    python manage.py migrate

    在这里插入图片描述

    用户登陆及状态保持

    通过上面的用户扩展写一个登陆注销的服务。

    user_index.html 这里添加一个用户注册的链接

    欢迎 {{ request.user }}来到商城系统!
    <a href="{% url 'myuser_logout' %}">用户退出a>
    
    <br />
    用户信息列表
    <table border="1">
      <tr>
        <td>账户td>
        <td>用户姓名td>
        <td>emailtd>
        <td>操作td>
      tr>
      <tr>
        <td>{{user.username}}td>
        <td>{{user.truename}}<td>
        <td>{{user.email}}td>
        <td>修改td>
      tr>
    table>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    user_index.html 首页的显示页面

    欢迎 {{ request.user }}来到商城系统!
    <a href="{% url 'myuser_logout' %}">用户退出a>
    
    <br />
    用户信息列表
    <table border="1">
      <tr>
        <td>账户td>
        <td>用户姓名td>
        <td>emailtd>
        <td>操作td>
      tr>
      <tr>
        <td>{{user.username}}td>
        <td>{{user.truename}}<td>
        <td>{{user.email}}td>
        <td>修改td>
      tr>
    table>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    views.py中添加了myuser_login用户登陆,myuser_logout是用户退出的操作,myuser_index是首页的显示,myuser_reg是用户注册的页面。

    def myuser_login(request):
        if request.method == "GET":
            return render(request, 'app1/login.html')
        if request.method == "POST":
            uname = request.POST.get("username", "")
            pwd = request.POST.get("password", "")
            if MyUser.objects.filter(username=uname):
                user = authenticate(username=uname, password=pwd)
                if user:
                    if user.is_active:
                        login(request, user)
                        info = '登陆成功'
                        return render(request, 'app1/user_index.html')
                    else:
                        info = '用户还没激活'
                else:
                    info = '账户密码不对,请重新输入'
            else:
                info = '用户账户不对,请查询'
    
            return render(request, 'app1/login.html', {"info": info, "user": user})
    
    
    def myuser_logout(request):
        logout(request)
        return redirect(reverse('app1_myuser_login'))
    
    
    def myuser_index(request):
        users = MyUser.objects.all()
        return render(request, 'app1/user_index.html', {"users": users})
    
    
    def myuser_reg(request):
        if request.method == "GET":
            return render(request, 'app1/user_reg.html')
        if request.method == "POST":
            uname = request.POST.get("username", "")
            pwd = request.POST.get("password", "")
            if MyUser.objects.filter(username=uname):
                info = '用户已经存在'
            else:
                d = dict(username=uname, password=pwd, email='111@111.com',
                         is_staff=1, is_active=1, is_superuser=1, weChat='yangcoder', level='1')
                user = MyUser.objects.create_user(**d)
                info = '注册成功,请登录'
    
            return redirect(reverse('app1_myuser_login'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    urls.py 这里添加的url带上了name属性,便于着模板中url中指向对应的视图。

        path('app1/myuser_logout/', views.myuser_logout, name="myuser_logout"),
        path('app1/myuser_reg/', views.myuser_reg, name="myuser_reg"),
        path('app1/myuser_login/', views.myuser_login, name="app1_myuser_login"),
    
    • 1
    • 2
    • 3

    权限管理

    Django认证系统默认对一个数据模型一共四个:查看view、增加add、修改charge、删除delete

    数据表auth_permission

    • id 主键
    • name 权限名称
    • content_type_id 模型关联的表
    • codename 具体权限

    权限认证的相关方法:

    • login.required 用户认证的资源访问装饰器,如果没通过,跳转settings.py中的LOGIN_URL路劲
    • permission_required 数据资源访问器
    • Require_GET / Require_POST 请求访问限制装饰器

    中间件

    和java的AOP一样,也是一种切面编程。Django的在配置文件settings.py的MIDDLEWARE列表中

    在这里插入图片描述

    中间件的方法:

    • process_request(self,request) 在处理请求之前调用
    • process_view(self, request, callback, callback_args, callback_kwargs) 在处理视图前的每个请求用
    • process_template_response(self, request, response) view()函数中的render()方法前调用
    • process_exception(self, request, exception) 在视图抛出异常时调用
    • process_response(self, request, response) 在处理响应后,所有响应返回浏览器之前被调用

    中间件简化权限认证

    from django.shortcuts import HttpResponse, render, redirect
    from django.utils.deprecation import MiddlewareMixin
    import re
    
    
    class PermissionMiddleWare(MiddlewareMixin):
        def process_request(self, request):
            # 获取当前路径
            curr_path = request.path
            print(curr_path)
            # 白名单处理
            white_list = ["/myuser_login/", "myuser_reg"]
            for w in white_list:
                if re.search(w, curr_path):
                    # 通过
                    return None
            # 是否登陆
            print(request.user.is_authenticated)
            if not request.user.is_authenticated:
                return redirect("app1/myuser_login/")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    中间件配置添加即可

    app1.middle.permiddleware.PermissionMiddleWare

  • 相关阅读:
    解决大模型行业落地三大挑战,华为云GaussDB向量数据库正式发布
    discuz、ecshop、帝国cms部署https(ssl)后会员无法登录
    {“Code“:“InvalidParameterValue.TemplateParameterFormatError“
    【supplemental】On_Distillation_of_CVPR_2023_supplemental
    猿创征文|活在大二,前端的我勇往直前
    Prime Ring Problem(素数环问题)
    1259:【例9.3】求最长不下降序列
    prometheus + grafana + node_exporter 搭建监控服务
    解析eclipse和idea运行java程序的过程
    透明窗体和控件
  • 原文地址:https://blog.csdn.net/qq_40801987/article/details/125454706