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.
    ...
View Code

用户登录

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.
        ...
View Code

如果你手动验证并使用户登录,那么你要先用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.
View Code

当用户退出后,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))
View Code
from django.shortcuts import render

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

装饰器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'
View Code

权限装饰器

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):
    ...
View Code

如果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):
    ...
View Code

如果你想使用django的认证系统,而又不想使用它的默认模版,可以通过在urlconf里附带参数的方式,指定自定义的模版

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

django 认证系统所有的views

login(requesttemplate_name=`registration/login.html`redirect_field_name='next',authentication_form=AuthenticationFormcurrent_app=Noneextra_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 %}
View Code

logout(requestnext_page=Nonetemplate_name='registration/logged_out.html'redirect_field_name='next',current_app=Noneextra_context=None)

logout_then_login(requestlogin_url=Nonecurrent_app=Noneextra_context=None)

password_change(requesttemplate_name='registration/password_change_form.html',post_change_redirect=Nonepassword_change_form=PasswordChangeFormcurrent_app=None,extra_context=None)

password_change_done(requesttemplate_name='registration/password_change_done.html',current_app=Noneextra_context=None)

password_reset(requestis_admin_site=Falsetemplate_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_generatorpost_reset_redirect=Nonefrom_email=Nonecurrent_app=None,extra_context=Nonehtml_email_template_name=Noneextra_email_context=None)

password_reset_done(requesttemplate_name='registration/password_reset_done.html'current_app=None,extra_context=None)

password_reset_confirm(requestuidb64=Nonetoken=None,template_name='registration/password_reset_confirm.html'token_generator=default_token_generator,set_password_form=SetPasswordFormpost_reset_redirect=Nonecurrent_app=Noneextra_context=None)

password_reset_complete(requesttemplate_name='registration/password_reset_complete.html',current_app=Noneextra_context=None)

原文地址:https://www.cnblogs.com/jijizhazha/p/5849791.html