- 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个字符
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', 'lennon@thebeatles.com', 'johnpassword') # saved
user.last_name = 'Lennon' # change other field
user.save()
创建superusers
$ python manage.py createsuperuser --username=joe --email=joe@example.com
修改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.