1、用戶認證與權限管理 — 繞不過去的需求
幾乎所有軟件項目都不得不實現(xiàn)的1個功能需求就是:用戶認證與權限管理。其基本要求包括:
- 提供用戶登入,登出,密碼更改,密碼重置等頁面。
- 對頁面操作、數(shù)據(jù)訪問的權限控制,包括增刪改查。
- 權限控制基于用戶、組、基于頁面、基于表。
說起來容易,實現(xiàn)起來卻非易事,特別是權限控制,通常需要基于表級,基于接口,一些項目要求權限管理基于字段級、行級,所以很多程序員提起權限細化都頭痛。
Django框架提供了完整的用戶認證與權限子系統(tǒng),符合 不重復發(fā)明輪子(Don’'t Re-invent Yourself) 理念,開發(fā)工程師可以集中精力于業(yè)務邏輯的開發(fā)。下面就介紹,如何利用 django auth模塊內(nèi)置視圖與組件,快速完成用戶認證及權限控制的開發(fā)。
需要指出,主流Python開發(fā)框架中只有Django提供了完整的用戶認證與權限管理功能,而且使用簡捷,支持定制擴展。Web類商業(yè)項目的開發(fā)工具,Django是1個非常靠譜的選擇
2、Django演示項目環(huán)境準備
2.1 運行環(huán)境準備
為了初學者閱讀方便,還是加上這一節(jié)吧
新建1個項目django-admin startproject myproject
新建app, 在此筆者創(chuàng)建的app名稱為 imgproccd myproject
python manage.py startapp imgproc
將app添加到項目配置文件
在setting.py 中將新建app加入INSTALLED_APPS
INSTALLED_APPS = [
......
'imgproc',
]
同步數(shù)據(jù)庫
python manage.py makemigrations
python manage.py migrate
運行項目
python manage.py runserver, 默認端口 8000
這時應該可以訪問 http://127.0.0.1:8000/ 了。
創(chuàng)建管理員帳號
python manage.py createsuperuser
訪問http://127.0.0.1:8000/admin/ 檢查登錄是否正常。
至此,項目運行環(huán)境創(chuàng)建就算完成了。
2.2 演示項目準備
演示項目的代碼及數(shù)據(jù)包括:,
- 創(chuàng)建1個model UploadFile
- 視圖函數(shù)與視圖類
- URL config
- 模板文件
- 數(shù)據(jù)庫測試數(shù)據(jù)
2.2.1 在imgproc應用中添加模型, models.py
# models.py
from django.db import models
from django.urls import reverse
# Create your models here.
class UploadFile(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.
class UploadFileAdmin(admin.ModelAdmin):
list_display = ['id','title','uploadfile']
admin.site.register(UploadFile,UploadFileAdmin)
2.2.3 編寫視圖函數(shù)與視圖類 views.py
為了演示,使用了內(nèi)置通用視圖方式與函數(shù)式編程兩個視圖,可能你都會用到。
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
class UploadfileListView(generic.ListView):
"""list all data """
model = UploadFile
template_name = "imgproc/uploadfile_list.html"
def download_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 編寫顯示數(shù)據(jù)的模板
在imgproc 下新建模板目錄
mkdir templates/imgproc/ 子目錄,創(chuàng)建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 添加測試數(shù)據(jù)并測試URL
通過 http://127.0.0.1:8000/admin/
, django 管理后臺, 添加一些測試數(shù)據(jù)。
通過 http://127.0.0.1:8000/image/list/
可以顯示所有數(shù)據(jù)
通過http://127.0.0.1:8000/image/download/1/
可以下載圖片。
3、用django內(nèi)置視圖完成用戶認證
django.contrib.auth 用戶認證模塊內(nèi)置了 User 模型與一套用戶認證視圖,直接使用這些組件開發(fā),讓用戶認證變得異常簡單,下面我們來看一下實現(xiàn)過程
3.1 導入內(nèi)置視圖的url
將auth模塊的內(nèi)置視的url加入在項目的urls,.py 中, 也就是myproject/myproject/urls.py 中添加:
urlpatterns = [
....,
path("accounts/", include("django.contrib.auth.urls")), # new
]
3.2 添加 login.html 登錄模板
在項目根目錄下,創(chuàng)建模板目錄
mkdir templates/registration/
cd templates/registration/
新建 login.html
...
<h2> 請登錄 </h2>
<form method="POST">
{% csrf_token %}
{{ form.as_p}}
<input type="submit" class="btn btn-success" value="登錄">
</form>
...
另外要為logout 登出后指定前轉(zhuǎn)頁面,在項目的配置文件 myproject/myproject/settings.py 中添加配置
LOGOUT_REDIRECT_URL = "/account/login/" # 登出后重定向頁面
3.3 Django內(nèi)置認證視圖提供的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行代碼,就完成了用戶認證的后端開發(fā),是不是很神奇。而且由于 django還是以安全性著稱的,實現(xiàn)的這些接口安全性也可有效保證。
4、權限管理的實現(xiàn)
本文開頭提到,權限管理需求包含: 基于頁面操作與數(shù)據(jù)操作的權限控制, 下面分別介紹如何實現(xiàn)
4.1 基于URL頁面的權限控制
思路就是,當用戶訪問url 頁面時,先檢查其是否已登錄,如果沒有登錄或用戶名密碼不對,前轉(zhuǎn)到登錄頁面。
實現(xiàn)這1過程也非常簡單
對于視圖函數(shù),前加1個裝飾器 @login_required
即可
from django.contrib.auth.decorators import login_required
@login_required(login_url='/accounts/login/')
def download_file_stream(request,fid=1):
......
實現(xiàn)功能: 如果request請求中的user 參數(shù)已登錄過,則繼續(xù)運行后面的語句,否則跳轉(zhuǎn)到登錄頁面。
對于類方式實現(xiàn)的視圖類,提供了LoginRequiredMixin基類,視圖類用多繼承方式來實現(xiàn)
from django.contrib.auth.mixins import LoginRequiredMixin
class MyView(LoginRequiredMixin, ListView):
login_url = '/accounts/login/'
注:LoginRequiredMixin一定要寫在 ListView前面。
4.2 基于用戶、表(模型)的數(shù)據(jù)訪問權限
4.2.1 Django 用戶數(shù)據(jù)權限管理的基本邏輯
當通過 makemigration 命令向數(shù)據(jù)庫添加模型(表)時,默認為每個 Django 模型創(chuàng)建了四個權限:添加add、修改change、刪除delete 和查看view。
在數(shù)據(jù)庫的 auth_permission表中,每張表都有4個權限: add, change, delete, view,
比如,對于演示項目的 Uploadfile 模型來說,當在數(shù)據(jù)庫中生成表時, 會在權限表 auth_permission 中,為Uploadfile 添加 4個權限,codename 字段值分別為:
- view_uploadfile
- add_uploadfile
- change_uploadfile
- delete_uploadfile
當你在管理后臺,創(chuàng)建用戶時,會列出上面的4個權限供選擇。
如果打開數(shù)據(jù)庫,會發(fā)現(xiàn) User表與auth_permission 權限表是1對多關系,因此還有1張表: auth_user_permission 關系表,記錄了每個user的賦予的權限。 可以通過該表查詢具體的權限,
4.2.2 如何給用戶添加數(shù)據(jù)操作權限
在管理后臺創(chuàng)建新用戶時,添加權限,每張表都可以指定增刪改查權限。無須編程實現(xiàn)。
可以進入 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 數(shù)據(jù)操作權限控制的實現(xiàn)
當客戶端通過URL來訪問數(shù)據(jù)時,如何判斷用戶是否有相應的操作權限呢?
**對于視圖函數(shù),**使用permission_required
裝飾器來檢查用戶是否有權限。
from django.contrib.auth.decorators import permission_required
@permission_required('imgproc.view_uploadfile')
#@permission_required(('imgproc.add_uploadfile')
def download_file(request,fid=1):
# …
如果要多檢查1項權限,只須再添加1條裝飾器語句。
對于視圖類,提供了PermissionRequiredMixin基類,通過多繼承方式實現(xiàn):
from django.contrib.auth.mixins import PermissionRequiredMixin
class UploadfileListView(PermissionRequiredMixin,generic.ListView):
"""list all data if user has view permission """
permission_required = ('imgproc.view_uploadfile', )
最多3行代碼,就提供了完整的基于用戶,基于表的數(shù)據(jù)操作權限控制。
@permission_required 失敗會前轉(zhuǎn)登錄頁面,(HTTP Status 302).
@PermissionRequiredMixin 失入發(fā)送403 (HTTP Status Forbidden).文章來源:http://www.zghlxwxcb.cn/news/detail-426945.html
5、總結(jié)
Django 的用戶認證與權限子系統(tǒng)提供了1種快速實現(xiàn)的方式,只用了不到 20 行代碼,就為項目添加了一套相當完善的用戶認證與權限控制功能。
如果要對用戶認證或權限做更深入的功能開發(fā),如基于字段控制權限,就需要進一步理解 django 框架模型類,User類, Permission類的基本工作原理,django也提供了豐富的接口用于定制化開發(fā)。文章來源地址http://www.zghlxwxcb.cn/news/detail-426945.html
到了這里,關于Django 不到20行代碼實現(xiàn)用戶認證及權限管理完整功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!