[Django1.8] Authentication

- Authentication安裝


django-admin startproject生成的settings.py, 默認包含必要的Auth配置:

INSTALLED_APPS:
1. 'django.contrib.auth' 包含認證框架的核心,及默認模塊。
2. 'django.contrib.contenttypes' 是Django的content type system, 使權限管理能關聯到你創建的模塊。跟蹤所有你在Django工程中安裝的模塊,提供一個高level的通用接口與模塊協同工作。

MIDDLEWARE_CLASSES:
1. SessionMiddleware 管理請求會話.
2. AuthenticationMiddleware 管理用戶和使用會話的請求.
3. SessionAuthenticationMiddleware 密碼改變後登出session.

有這些設置,運行manage.py migrate會創建auth相關模塊的必要數據庫表,及自定義apps的權限。


Auth用法:
使用Django的默認實現  https://docs.djangoproject.com/en/1.8/topics/auth/default/
默認實現的API參考     https://docs.djangoproject.com/en/1.8/ref/contrib/auth/
自定義Users和Authentication  https://docs.djangoproject.com/en/1.8/topics/auth/customizing/
Django中的密碼管理  https://docs.djangoproject.com/en/1.8/topics/auth/passwords/



- 使用Django默認實現的Authentication


-- Auth的對象模型 django.contrib.auth.models

models.User


域:
username*  不超過30個字符,alphanumeric, _, @, +, . and - characters
first_name  不超過30個字符 
last_name  不超過30個字符
email 
password*
groups            與Group多對多關係
user_permissions  與Permission多對多關係
is_staff     是否可以訪問Admin
is_active    推薦不要刪除賬號,而是設置此標誌爲False,這樣不會破壞可能的外鍵關聯。
is_superuser 是否擁有所有權限
last_login   最後登錄datetime, 未登錄過爲null
date_joined  賬號創建時間

(*表示必要的字段)

方法:
email_user(subject, message, from_email=None, **kwargs) 給用戶發送郵件
(from_email=None,使用DEFAULT_FROM_EMAIL; **kwargs 傳給內部的send_mail())

models.UserManager

create_user(username, email=None, password=None, **extra_fields)
創建、保存並返回User:
password爲None,則set_unusable_password()被調用;
email的域名部分被轉換爲小寫;
is_active設爲True;
extra_fields被傳遞給User的__init__方法,以設置自定義User的任意字段。

create_superuser(username, email, password, **extra_fields)
與create_user相同,但is_staff和is_superuser設置爲True.

models.AnonymousUser

實現User接口,通常不需要使用,而是被Web請求使用。

models.Permission

name*  不超過255個字符
content_type*  引用django_content_type庫表
codename*  不超過100個字符

models.Group

name*  不超過80個字符
permissions  與Permission多對多關係

登入和登出(可監聽)信號

user_logged_in()
user_logged_out()
user_login_failed()


-- 用戶對象

創建users
from django.contrib.auth.models import User
user = User.objects.create_user('john', '[email protected]', 'johnpassword') # saved
user.last_name = 'Lennon' # change other field
user.save()

創建superusers
$ python manage.py createsuperuser --username=joe [email protected]

修改passwords
命令行修改: manage.py changepassword *username*
程序修改: User.set_password()
admin界面修改

驗證(authenticating)用戶
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
    if user.is_active:
        print("User is valid, active and authenticated")
    else:
        print("The password is valid, but the account has been disabled!")
else:
    print("The username and password were incorrect.")

-- 在web請求中使用Authentication

Django使用sessions和middleware來綁定認證系統(authentication system)的請求對象(request objects), 
當前用戶的每個請求都提供了一個request.user屬性,如果當前用戶未登錄,此屬性被設置爲AnonymousUser對象,
否則設置爲User對象。
if request.user.is_authenticated():
    # Do something for authenticated users.
else:
    # Do something for anonymous users.


--- 用戶登入


from django.contrib.auth import authenticate, login


def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
            ...
    else:
        # Return an 'invalid login' error message.
        ...


--- 用戶登出


from django.contrib.auth import logout


def logout_view(request):
    logout(request)
    # Redirect to a success page.


--- 限制登錄用戶才能訪問


1.
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))
    # ...


2.
from django.shortcuts import render


def my_view(request):
    if not request.user.is_authenticated():
        return render(request, 'myapp/login_error.html')
# ...


3. 使用修飾符 login_required(redirect_field_name='next', login_url=None)
from django.contrib.auth.decorators import login_required


@login_required
def my_view(request):
    ...
如果用戶沒有登錄,重定向到settings.LOGIN_URL, 當前訪問路徑作爲查詢參數傳入。


--- Authentication的默認Views
from django.contrib.auth.views

配置:

urlpatterns = [
    url('^', include('django.contrib.auth.urls'))
]

urlpatterns = [
    url(
        '^change-password/',
        auth_views.password_change,
        {'template_name': 'change-password.html'}
    )
]

from django.contrib.auth import views

def change_password(request):
    template_response = views.password_change(request)
    # Do something with `template_response`
    return template_response

views默認方法:

login(request, template_name=`registration/login.html`, redirect_field_name=, authentication_form, current_app, extra_context])
logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name='next', current_app=None, extra_context=None)
logout_then_login(request, login_url=None, current_app=None, extra_context=None)
password_change(request, template_name='registration/password_change_form.html', post_change_redirect=None,
                password_change_form=PasswordChangeForm, current_app=None, extra_context=None)
password_change_done(request, template_name='registration/password_change_done.html', current_app=None, extra_context=None)
password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', 
               subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, 
  post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None)
password_reset_done(request, template_name='registration/password_reset_done.html', current_app=None, extra_context=None)
password_reset_confirm(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, 
                       set_password_form=SetPasswordForm, post_reset_redirect=None, current_app=None, extra_context=None)
password_reset_complete(request, template_name='registration/password_reset_complete.html', current_app=None, extra_context=None)

--- 內建的forms
django.contrib.auth.forms

AdminPasswordChangeForm
AuthenticationForm
PasswordChangeForm
PasswordResetForm   生成並郵件發送一次性使用的link,來重置密碼。
SetPasswordForm     不輸入舊密碼
UserChangeForm       admin
UserCreationForm     創建新用戶 


--- 在templates中使用Authentication信息

渲染模板的RequestContext時,用戶對象存儲在模板變量{{ user }}中。
{% if user.is_authenticated %}
    <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
    <p>Welcome, new user. Please log in.</p>
{% endif %}


權限模板變量

In the {{ perms }} object, single-attribute lookup is a proxy to User.has_module_perms. 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章