[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. 


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