zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    LeetCode 515. 在每个树行中找最大值(Find Largest Value in Each Tree Row)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 1022. 从根到叶的二进制数之和(Sum of Root To Leaf Binary Numbers)
    LeetCode 897. 递增顺序查找树(Increasing Order Search Tree)
    LeetCode 617. 合并二叉树(Merge Two Binary Trees)
    LeetCode 206. 反转链表(Reverse Linked List) 16
    LeetCode 104. 二叉树的最大深度(Maximum Depth of Binary Tree)
    LeetCode 110. 平衡二叉树(Balanced Binary Tree) 15
    LeetCode 108. 将有序数组转换为二叉搜索树(Convert Sorted Array to Binary Search Tree) 14
  • 原文地址:https://www.cnblogs.com/jijizhazha/p/5849791.html
Copyright © 2011-2022 走看看