django 认证系统--3
WEB request中的认证
django使用sessions和middleware和reqeust对象联系在一起
它们通过给每一个reqeust请求添加一个request.user属性来代表当前用户。如果用户没有登录,那么request.user将是AnonymousUser的对象,如果登录了,那么就是User的对象
if request.user.is_authenticated(): # Do something for authenticated users. ... else: # Do something for anonymous users. ...
用户登录
login()能够将通过认证的用户加入到当前回话
login(reqeust,user)
login()函数使用HttpRequest和User对象。login()使用session框架在session中保存当前用户id,
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. ...
如果你手动验证并使用户登录,那么你要先用authticate()然后在login(),authticate()会在user中设置一个属性,标记那个认证后台成功验证了该用户。
当用户登录后,用户ID和被用来认证该用户的后台被保存在了该用户的session中。在session中保存认证后台的选择顺序是:
1、使用提供的作为参数的后台的值
2、使用authticate()函数添加的后台
3、如果settings中AUTHENTICATION_BACKENDS中只有一个的话,使用它
4、引发一个错误。
用户退出
logout()该函数没有返回值,且不会抛出任何错误信息
from django.contrib.auth import logout def logout_view(request): logout(request) # Redirect to a success page.
当用户退出后,session中关于该用户的所有信息都会清除。
限制用户访问
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))
from django.shortcuts import render def my_view(request): if not request.user.is_authenticated(): return render(request, 'myapp/login_error.html')
装饰器login_required()
login_required(redirect_field_name='next',login_url=None)
该函数做如下工作:
1、如果用户没有登录,重定向到 settings.LOGIN_URL,并把当前访问网页的绝对路径作为查询部分传入到url中。如:/accounts/login/?next=/polls/3/
2、如果用户登录了,直接执行函数。
默认情况下,需要登录之后才能访问的url存放在next中,你可以通过更改redirect_field_name来更换名字。但是你需要自定义你的login 模版。
如果settings.LOGIN_URL中没有指定url或者是url名。那么就需要在该函数中指定。
login_required不检查用户的 is_active标志
LoginRequired mixin
如果使用基于类的 views,那么可以使用LoginRequired mixin 实现和login_required相同的效果
from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): login_url = '/login/' redirect_field_name = 'redirect_to'
权限装饰器
permission——required(perm,login_url=None,raise_exception=False)
from django.contrib.auth.decorators import permission_required @permission_required('polls.can_vote') def my_view(request): ...
如果raise_exception改为True,那么就会引发一个PermissionDenied错误,提示404views,而不是跳转到登录页面
如果你即想引发错误,又向允许用户登录,可以同时提供login_required装饰器
from django.contrib.auth.decorators import login_required, permission_required @login_required @permission_required('polls.can_vote', raise_exception=True) def my_view(request): ...
如果你想使用django的认证系统,而又不想使用它的默认模版,可以通过在urlconf里附带参数的方式,指定自定义的模版
urlpatterns = [ url( '^change-password/$',auth_views.password_change, {'template_name': 'change-password.html'} ), ]
django 认证系统所有的views
login(request, template_name=`registration/login.html`, redirect_field_name='next',authentication_form=AuthenticationForm, current_app=None, extra_context=None)
登录成功之后,会跳转到next中的url,如果没有指定那么就会跳转到settings.LOGIN_REDIRECT_URL
login.html中的一部分
{% extends "base.html" %} {% block content %} {% if form.errors %} <p>Your username and password didn't match. Please try again.</p> {% endif %} {% if next %} {% if user.is_authenticated %} <p>Your account doesn't have access to this page. To proceed, please login with an account that has access.</p> {% else %} <p>Please login to see this page.</p> {% endif %} {% endif %} <form method="post" action="{% url 'login' %}"> {% csrf_token %} <table> <tr> <td>{{ form.username.label_tag }}</td> <td>{{ form.username }}</td> </tr> <tr> <td>{{ form.password.label_tag }}</td> <td>{{ form.password }}</td> </tr> </table> <input type="submit" value="login" /> <input type="hidden" name="next" value="{{ next }}" /> </form> {# Assumes you setup the password_reset view in your URLconf #} <p><a href="{% url 'password_reset' %}">Lost password?</a></p> {% endblock %}
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, extra_email_context=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)