当前位置:   article > 正文

Django 用户认证

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>email</td>
    <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>email</td>
    <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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/71666
推荐阅读
相关标签
  

闽ICP备14008679号