0


Django 不到20行代码实现用户认证及权限管理完整功能

1、用户认证与权限管理 — 绕不过去的需求

几乎所有软件项目都不得不实现的1个功能需求就是:用户认证与权限管理。其基本要求包括:

  • 提供用户登入,登出,密码更改,密码重置等页面。
  • 对页面操作、数据访问的权限控制,包括增删改查。
  • 权限控制基于用户、组、基于页面、基于表。

说起来容易,实现起来却非易事,特别是权限控制,很多程序员提起权限细化都头痛。

需要先赞一下Django的用户认证与权限子系统,认认真真地落实 不重复发明轮子(Don’'t Re-invent Yourself) ** 理念,让程序猿们可以集中精力于业务逻辑的开发。下面就介绍,如何利用 django auth模块内置视图与组件,快速完成用户认证及权限控制的开发**。

2、Django演示项目环境准备

2.1 运行环境准备

为了初学者阅读方便,还是加上这一节吧

新建1个项目

django-admin startproject myproject

新建app, 在此笔者创建的app名称为 imgproc

cd myproject
python manage.py startapp imgproc

将app添加到项目配置文件
在setting.py 中将新建app加入INSTALLED_APPS

INSTALLED_APPS = [
    ......
    'imgproc',
]

同步数据库

python manage.py makemigrations
python manage.py migrate

运行项目
python manage.py runserver, 默认端口 8000
这时应该可以访问 http://127.0.0.1:8000/ 了。

创建管理员帐号
python manage.py createsuperuser
访问http://127.0.0.1:8000/admin/ 检查登录是否正常。

至此,项目运行环境创建就算完成了。

2.2 演示项目准备

演示项目的代码及数据包括:,

  • 创建1个model UploadFile
  • 视图函数与视图类
  • URL config
  • 模板文件
  • 数据库测试数据

2.2.1 在imgproc应用中添加模型, models.py

# models.py from django.db import models
from django.urls import reverse

# Create your models here.classUploadFile(models.Model):
    title = models.CharField(max_length=30)
    uploadfile = models.ImageField(upload_to="upload/")def__str__(self)->str:return self.title

2.2.2 将model 加入后台 admin.py

from django.contrib import admin
from  imgproc.models import*# Register your models here.classUploadFileAdmin(admin.ModelAdmin):
    list_display =['id','title','uploadfile']

admin.site.register(UploadFile,UploadFileAdmin)

2.2.3 编写视图函数与视图类 views.py

为了演示,使用了内置通用视图方式与函数式编程两个视图,可能你都会用到。

from django.shortcuts import render,redirect
from django.http import HttpResponse, FileResponse
# Create your views here.from imgproc.forms import*from imgproc.models import*from django.views import generic
from django.urls import reverse_lazy
import os

classUploadfileListView(generic.ListView):"""list all data """
    model = UploadFile
    template_name ="imgproc/uploadfile_list.html"defdownload_file_stream(request,fid=1):""" Send file with FileResponse """
    obj = UploadFile.objects.get(pk=fid)
    fpath = os.path.join(settings.MEDIA_ROOT, obj.uploadfile.name)print(fpath)
    response = FileResponse(open(fpath,'rb'))
    response['Content-Type']='application/octet-stream'
    response["Content-Disposition"]="attachment; filename=test.jpg"return response

2.2.4 URL config 配置

myproject/myproject/urls.py

from django.contrib import admin
from django.urls import path,re_path,include

urlpatterns =[
    path('admin/', admin.site.urls),
    path('image/',include("imgproc.urls")),]

imgproc.urls.py 代码

from django.urls import path,re_path
from imgproc.views import*

urlpatterns =[
name="upload_file_update"),
    path("list/", UploadfileListView.as_view(), name="upload_file_list"),
    path("download/<int:fid>/",download_file_stream, name="download_file"),]

2.2.5 编写显示数据的模板

在imgproc 下新建模板目录
mkdir templates/imgproc/ 子目录,创建template 文件 uploadfile_list.html, base.html 里引入了bootsrap4 来渲染

{% comment %}  uploadfile_list.html {% endcomment %}{% extends './base.html'%}{% block content %}{% load static %}<div class="p-3 align-self-center border border-1 bg-light shadow-lg "><h2>uploadfiles </h2><ul class="list-group">{%for d in object_list %}<li class="list-group-item">{{ d.id}},{{ d.title }},{{ d.uploadfile }}</li>{% endfor %}</ul></div>{% endblock %}

2.2.6 添加测试数据并测试URL

通过

http://127.0.0.1:8000/admin/ 

, django 管理后台, 添加一些测试数据。
通过

http://127.0.0.1:8000/image/list/

可以显示所有数据
在这里插入图片描述
通过

http://127.0.0.1:8000/image/download/1/ 

可以下载图片。

3、用django内置视图完成用户认证

django.contrib.auth 用户认证模块内置了 User 模型与一套用户认证视图,直接使用这些组件开发,让用户认证变得异常简单,下面我们来看一下实现过程

3.1 导入内置视图的url

将auth模块的内置视的url加入在项目的urls,.py 中, 也就是myproject/myproject/urls.py 中添加:

urlpatterns =[...., 
    path("accounts/", include("django.contrib.auth.urls")),# new]

3.2 添加 login.html 登录模板

在项目根目录下,创建模板目录
mkdir templates/registration/
cd templates/registration/
新建 login.html

...<h2> 请登录 </h2><form method="POST">{% csrf_token %}{{ form.as_p}}<inputtype="submit"class="btn btn-success" value="登录"></form>...

另外要为logout 登出后指定前转页面,在项目的配置文件 myproject/myproject/settings.py 中添加配置

LOGOUT_REDIRECT_URL = "/account/login/"        # 登出后重定向页面

3.3 Django内置认证视图提供的url

在URL config中添加了

include("django.contrib.auth.urls") 

之后,就可以使用以下用户认址的URL 接口了, 包含用户登录,登出,修改密码,密码确认,重置密码等页面。

accounts/login/ [name='login']   
accounts/logout/ [name='logout']
accounts/password_change/ [name='password_change']
accounts/password_change/done/ [name='password_change_done']
accounts/password_reset/ [name='password_reset']
accounts/password_reset/done/ [name='password_reset_done']
accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/reset/done/ [name='password_reset_complete']

3.4 测试

尝试一下用管理员帐户登录

http://127.0.0.1:8000/accounts/login/ 

以及修改密码等URL

总共只用了2行代码,就完成了用户认证的后端开发,是不是很神奇。而且由于 django还是以安全性著称的,实现的这些接口安全性也可有效保证。

4、权限管理的实现

本文开头提到,权限管理需求包含: 基于页面操作与数据操作的权限控制, 下面分别介绍如何实现

4.1 基于URL页面的权限控制

思路就是,当用户访问url 页面时,先检查其是否已登录,如果没有登录或用户名密码不对,前转到登录页面

实现这1过程也非常简单
对于视图函数,前加1个装饰器

@login_required

即可

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')defdownload_file_stream(request,fid=1):......

实现功能: 如果request请求中的user 参数已登录过,则继续运行后面的语句,否则跳转到登录页面。

对于类方式实现的视图类,提供了LoginRequiredMixin基类,视图类用多继承方式来实现

from django.contrib.auth.mixins import LoginRequiredMixin

classMyView(LoginRequiredMixin, ListView):
    login_url ='/accounts/login/'

注:LoginRequiredMixin一定要写在 ListView前面。

4.2 基于用户、表(模型)的数据访问权限

4.2.1 Django 用户数据权限管理的基本逻辑

当通过 makemigration 命令向数据库添加模型(表)时,默认为每个 Django 模型创建了四个权限:添加add、修改change、删除delete 和查看view。

在数据库的 auth_permission表中,每张表都有4个权限: add, change, delete, view,
比如,对于演示项目的 Uploadfile 模型来说,当在数据库中生成表时, 会在权限表 auth_permission 中,为Uploadfile 添加 4个权限,codename 字段值分别为:

  • view_uploadfile
  • add_uploadfile
  • change_uploadfile
  • delete_uploadfile

当你在管理后台,创建用户时,会列出上面的4个权限供选择。
如果打开数据库,会发现 User表与auth_permission 权限表是1对多关系,因此还有1张表: auth_user_permission 关系表,记录了每个user的赋予的权限。 可以通过该表查询具体的权限,

4.2.2 如何给用户添加数据操作权限

管理后台创建新用户时,添加权限,每张表都可以指定增删改查权限。无须编程实现。

可以进入 python manage,py shell 来检验一下用户权限(可以跳过此步),
如下例 ,新建用户test01, 在模型 uploadfile上有add权限,但没有 user模型的add权限, 对于 test01 用户,可以用 has_perm()方法来验证其在 两个模型上的权限

In [13]: user1 = User.objects.get(username="test01")
In [15]: user1.has_perm("imgproc.add_uploadfile")
Out[15]: True
In [16]: user1.has_perm("imgproc.add_user")
Out[16]: False

4.2.3 数据操作权限控制的实现

当客户端通过URL来访问数据时,如何判断用户是否有相应的操作权限呢?
对于视图函数,使用

permission_required

装饰器来检查用户是否有权限。

from django.contrib.auth.decorators import permission_required

@permission_required('imgproc.view_uploadfile')#@permission_required(('imgproc.add_uploadfile')defdownload_file(request,fid=1):# …

如果要多检查1项权限,只须再添加1条装饰器语句。

对于视图类,提供了PermissionRequiredMixin基类,通过多继承方式实现:

from django.contrib.auth.mixins import PermissionRequiredMixin

classUploadfileListView(PermissionRequiredMixin,generic.ListView):"""list all data if user has view permission """
     permission_required =('imgproc.view_uploadfile',)

最多3行代码,就提供了完整的基于用户,基于表的数据操作权限控制。

@permission_required 失败会前转登录页面,(HTTP Status 302).
@PermissionRequiredMixin 失入发送403 (HTTP Status Forbidden).

5、总结

Django 的用户认证与权限子系统提供了1种快速实现的方式,只用了不到 20 行代码,就为项目添加了一套相当完善的用户认证与权限控制功能。
如果要对用户认证或权限做更深入的功能开发,如基于字段控制权限,就需要进一步理解 django 框架模型类,User类, Permission类的基本工作原理,django也提供了丰富的接口用于定制化开发。

标签: django python 后端

本文转载自: https://blog.csdn.net/captain5339/article/details/128234437
版权归原作者 __弯弓__ 所有, 如有侵权,请联系我们删除。

“Django 不到20行代码实现用户认证及权限管理完整功能”的评论:

还没有评论