【Django】Django Auth認證組件詳述

  • 2020 年 2 月 14 日
  • 筆記

1、Django Auth介紹

官方文檔:https://docs.djangoproject.com/en/1.10/topics/auth。 Django內置了用戶認證系統,處理用戶賬戶、用戶組、權限,基於cookie的session,並且內置了一些快捷函數。Auth App有自己的數據庫系統,有自己的ORM。

Requirements
  • INSTALLED_APPS
    • 「django.contrib.auth」
    • 「django.contrib.contenttypes」
  • MIDDLEWARE need
    • 「SessionMiddleware」
    • 「AuthenticationMiddleware」

2、Django Auth中的數據庫表和對象

User Objects
  • fields 字段
    • username
    • password
    • email
    • first_name
    • last_name
    • groups
    • user_permission
    • is_staff
    • is_active
    • is_superuser
    • last_login
    • date_joined
  • attr 屬性
    • is_authenticated
    • is_anonymous
    • username_validator
  • method 方法
    • get_username
    • get_full_name
    • get_short_name
    • set_password
    • check_password
    • set_unusable_password
    • has_usable_password
    • get_group_permissions
    • get_all_permissions
    • has_perm
    • has_module_perms
    • email_user
AnonymousUser

django.contrib.auth.models.AnonymousUser is a class that implements the django.contrib.auth.models.User interface, with these differences:

  • id is always None.
  • username is always the empty string.
  • get_username() always returns the empty string.
  • is_anonymous is True instead of False.
  • is_authenticated is False instead of True.
  • is_staff and is_superuser are always False.
  • is_active is always False.
  • groups and user_permissions are always empty.
  • set_password(), check_password(), save() and delete() raise NotImplementedError.

3、權限管理

Permission model

Permission objects have the following fields:

  • class models.Permission.name Required. 255 characters or fewer. Example: 『Can vote』.
  • content_type Required. A reference to the django_content_type database table, which contains a record for each installed model.
  • codename Required. 100 characters or fewer. Example: 『can_vote』.
Group model

fields

  • name
  • permissions Many-to-many field to Permission:
group.permissions.set([permission_list])  group.permissions.add(permission, permission, ...)  group.permissions.remove(permission, permission, ...)  group.permissions.clear()
創建用戶
>>> from django.contrib.auth.models import User  >>> user = User.objects.create_user('john', '[email protected]', 'johnpassword')    # At this point, user is a User object that has already been saved to the database.  # You can continue to change its attributes, if you want to change other fields.  >>> user.last_name = 'Lennon'  >>> user.save()    $ python manage.py createsuperuser --username=joe [email protected]
更改密碼
>>> from django.contrib.auth.models import User  >>> u = User.objects.get(username='john')  >>> u.set_password('new password')  >>> u.save()    $ python manage.py changepassword joe
認證、登錄和登出
from django.contrib.auth import authenticate, login, logout    def my_view(request):  	username = request.POST['username']  	password = request.POST['password']  	user = authenticate(username=username, password=password)  	if user is not None:  		login(request, user)  		# Redirect to a success page.  		...  	else:  		# Return an 'invalid login' error message.    def logout_view(request):  	logout(request)  	# Redirect to a success page.

4、Authentication Web

普通方式
from django.conf import settings  from django.shortcuts import redirect    def my_view(request):  	if not request.user.is_authenticated:  		return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))  	else:  		do_something()
使用裝飾器
from django.contrib.auth.decorators import login_required    @login_required  def my_view(request):  	...
  • 如果用戶沒有登錄,會重定向到settings.LOGIN_URL,如/accounts/login/?next=/polls/3/
  • next後面跟的是登錄成功後跳轉的URL
  • next的名字可以自定義
  • 重定向的登錄URL可以自定義
@login_required(redirect_field_name='go', login_url="/user/login/")  def my_view(request):  	...

5、授權

Permission model

Fields:

  • name(『Can vote』)
  • content_type (A reference to the django_content_type database table)
  • codename(『can_vote』)
The ContentType model

Fields:

  • app_label
  • model

參考數據庫默認添加的Permission和Content type,了解每張表的作用。

用戶權限
>>> from django.contrib.auth.models import User, Permission, ContentType  >>> user = User.objects.create_user(username='ibuler', email='[email protected]'  >>> permission = Permission.objects.get(codename='add_question')  >>> user.user_permissions.add(permission)  >>> user.has_perm('polls.add_question')  >>> content_type = ContentType.objects.get(app_label='polls', model='choice')  >>> permission = Permission.objects.create(name='Can vote', codename='can_vote', content_type=content_type)  >>> user.user_permissions.add(permission)  >>> user.have_perm('polls.can_vote')
  • has_perm(『app_label.codename』)
用戶組權限
>>> sa = Group.objects.create(name='sa')  >>> sa.user_set.add(user)  >>> sa.save()  >>> permission = Permission.objects.get(codename='add_user')  >>> sa.permissions.add(permission)  >>> user.has_perm('auth.add_user')
  • 用戶會繼承用戶組的權限
view使用
from django.contrib.auth.decorators import permission_required    @permission_required('polls.can_vote', login_url='/loginpage/')  def my_view(request):  	...

6、Cookie and Session

http協議沒有狀態,cookie讓http請求的時候攜帶狀態,cookie保存在瀏覽器緩存中,和域名有關。 Request Headers:

...  Connection:keep-alive  Cookie:csrftoken=7YeO6nvnQMWEtreWglxBhJfQ4NT2SO5yBmsp73ZcuL5TBCBIeXDcznADfGXuhqHV; sessionid=j7sg4b9iis8pjh075s303uelm01jydn8  ...

cookie based sessions:session是基於cookie來做的,只不過保存了一個session id,所有其他內容都在服務器端存儲,用來鑒別用戶是否登錄,以及其他信息,session要比完全cookie安全。 cookie和session相關函數、屬性和model:

  • request.set_cookie:設置當前請求的cookie
  • request.cookie
  • request.session:設置當前請求的session
  • django.contrib.sessions.models.Session

7、Django Admin

Django強大的功能之一就是提供了Admin後台管理界面,簡單配置就可以對數據庫內容做管理。

Requirement
  • 添加』django.contrib.admin』到INSTALLED_APPS設置中。
  • admin有四個依賴:
    • django.contrib.auth
    • django.contrib.contenttypes
    • django.contrib.messages
    • django.contrib.sessions 如果這些應用沒有在INSTALLED_APPS列表中,那你要把它們添加到該列表中。
  • 把django.contrib.messages.context_processors.messages添加到TEMPLATES中DjangoTemplates後台的 『context_processors』 選項中,同樣把django.contrib.auth.middleware.AuthenticationMiddleware和django.contrib.messages.middleware.MessageMiddleware添加到MIDDLEWARE_CLASSES.(這些默認都是激活的,所以如果你手工操作過的話就需要按照以上方法進行設置)
  • URLconf包含url(r』^admin/』, admin.site.urls)
  • 修改${app_dir}/admin.py,給每個模型創建一個ModelAdmin類,封裝模型自定義的Admin功能和選項。
  • 註冊ModelAdmin。做了這些步驟之後,你將能夠通過你已經綁定的URL來訪問Django管理站點(默認是/admin/)。
登錄Admin後台管理界面
  • 創建管理員用戶
  • 訪問http://$host/admin/
創建ModelAdmin並註冊
from django.contrib import admin  from .models import Author, Book, Publisher    # version 1  admin.site.register(Author)    # version 2  class AuthorAdmin(admin.ModelAdmin):  	pass    admin.site.register(Author, AuthorAdmin)    #version 3  @admin.register(Author)  class AuthorAdmin(admin.ModelAdmin):  	pass    @admin.register(Book)  class BookAdmin(admin.ModelAdmin):  	pass    @admin.register(Publisher)  class PublisherAdmin(models.ModelAdmin):  	pass

說明:

  • 會自動去app下尋找admin模塊
  • 自動根據model的Field類型設置Form類型
配置ModelAdmin
  • label名稱,定義Model Field時指定verbose_name
  • 排除某些字段exclude
  • 顯示某字段fields
  • 搜索某列search_fields
  • 添加日期標籤過濾date_hierarchy
  • 排序ordering
  • 列表顯示更多列list_display
@admin.register(Book)  class BookAdmin(admin.ModelAdmin):  	fields = ('title', 'authors', 'publisher')  	search_fields = ('title', 'authors')  	date_hierarchy = 'publication_date'  	ordering = ('publication_date',)    @admin.register(Publisher)  class PublisherAdmin(admin.ModelAdmin):  	list_display = ('name', 'country', 'city', 'address')    def display_book_authors(obj):			# 多對多關係  	return ', '.join([author.first_name for author in obj.authors.all()])    display_book_authors.short_description = 'Authors'    class BookAdmin(admin.ModelAdmin):  	list_display = ['title', 'publisher', display_book_authors, 'publication_date']
配置Action
def make_book_pub_date_to_now(modeladmin, request, queryset):  	queryset.update(publication_date=timezone.now())    make_book_pub_date_to_now.short_description = 'Mark selected book pub_date as now'    @admin.register(Book)  class BookAdmin(admin.ModelAdmin):  	list_display = ['title', 'publisher', 'publication_date']  	actions = [make_book_pub_date_to_now]

8、Django Settings

詳見:https://docs.djangoproject.com/en/1.10/ref/settings/