zoukankan      html  css  js  c++  java
  • [django]总结Django中的用户权限模块

    出处:http://blog.csdn.net/zeng_84_long/article/details/8153993

    此文是总结Django官方网站里面的Document的文章 User authentication in Django
    http://www.djangoproject.com/documentation/authentication/


    http://www.cnblogs.com/lddhbu/archive/2012/06/26/2564072.html


    该模块由
    用户(Users)
    权限(Permissions)
    组(Groups)
    消息(Messages)

    这些从字面上也都很好的理解,但是我对消息(Messages)还不是很理解…………


    1、安装
    1)将'django.contrib.auth'添加到Setting.py的INSTALLED_APPS 中
    2)安装数据库 manage.py syncdb.
    其实用户权限模块是Django自己已经写好的app,所以他也具有自身的Models,所以需要同步数据库。

    2、User
    1)属性
    其中他包含User类,他具有以下字段
    username,first_name,last_name,email,password,is_staff(是否具有进入网站管理权限),
    is_active,is_superuser,last_login,date_joined.

    这是Django自带的User的基本的信息,如果你要使用该权限模块,就必须要使用他的User类,
    但是通常情况下,我们的用户信息还会有其他的属性,这时我们可以再增加一类来扩展,该类和User的关系是OneToOne。
    如:
    #这是china-django中的代码

    class Profile(models.Model):
        user 
    = models.OneToOneField(User)

        blog 
    = models.CharField(maxlength=128, blank=True)
        location 
    = models.CharField(maxlength=128, blank=True)
        occupation 
    = models.CharField(maxlength=64, blank=True)
        
        reward 
    = models.IntegerField(default=0, blank=True)
        topic_count 
    = models.IntegerField(default=0, blank=True)
        post_count 
    = models.IntegerField(default=0, blank=True)
        
        
    class Admin:
            list_display 
    = ('user''blog''location''occupation''reward''topic_count''post_count')

    2)方法
    这里列举几个主要的方法
    is_anonymous():是否为匿名用户,如果你已经login,则这个方法返回始终为false.
    is_authenticated():是否通过验证,也就是通过用户名和密码判断该用户是否存在.
    get_group_permissions():得到所有该用户所属组别的权限.
    get_all_permissions():得到该用户所有的权限.
    has_perm(perm):判断用户是否具有特定权限,perm的格式是appname.codename.
    email_user(subject, message, from_email=None):给某用户发送邮件


    3) AnonymousUser
    AnonymousUser是继承自User接口,但是和User有不同处:
    id属性为None
    is_anonymous() 返回始终为True
    is_authenticated() 返回始终为False
    has_perm() 返回始终为False
    set_password(), check_password(), save(), delete(), set_groups()和set_permissions() 都会触发 NotImplementedError错误


    3、User的验证
    1)登陆(Login)

    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:
            login(request, user)
            
    # Redirect to a success page.
        else:
            
    # Return an error message.

    首先我们要验证这个用户,然后再登陆,登陆成功后,我们可以通过request.user 来得到当前登陆的用户对象。

    2)注销(Logout)

    from django.contrib.auth import logout

    def logout_view(request):
        logout(request)
        
    # Redirect to a success page.

    3)限制非法用户访问
    最普通的方法是通过request.user.is_authenticated()来判断

    from django.http import HttpResponseRedirect

    def my_view(request):
        
    if not request.user.is_authenticated():
            
    return HttpResponseRedirect('/login/?next=%s' % request.path)
        
    # 

    另外有一快捷的方法login_required

    from django.contrib.auth.decorators import login_required

    @login_required
    def my_view(request):
        
    # 

    这样当你访问my_view的时候,就需要用户需要通过验证.若不通过则跳转到
    /accounts/login/?next=/polls/3/
    并将当前访问的页面作为他的一个参数,并且传递三个Context变量
    form 一个FormWrapper 对象用来重构登陆表单
    next 就是你访问的当前页面
    site_name 当前站点名称,在Setting.py中设置SITE_ID的值

    另外,我们还需要在你的urls里面配置/accounts/login路径
    下面有两种两种,不同的是使用不同的模版,第一种默认使用registration/login.html 模版,第二种方式是我们自定义模版

    (r'^accounts/login/$''django.contrib.auth.views.login'),
    (r
    '^accounts/login/$''django.contrib.auth.views.login', {'template_name''myapp/login.html'}),

    一个login.html模版的实例:

    {% extends "base.html" %}

    {% block content %}

    {% if form.has_errors %}
    <p>Your username and password didn't match. Please try again.</p>
    {% endif %}

    <form method="post" action=".">
    <table>
    <tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr>
    <tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr>
    </table>

    <input type="submit" value="login" />
    <input type="hidden" name="next" value="{{ next }}" />
    </form>

    {% endblock %}

    4)用户是否有权限访问

    当我们创建了一个带有class Admin:内类的类后,会自动add, create 和 delete三种权限,不过我们也可以自己定义权限。
    如下:

    class USCitizen(models.Model):
        
    # 
        class Meta:
            permissions 
    = (
                (
    "can_drive""Can drive"),
                (
    "can_vote""Can vote in elections"),
                (
    "can_drink""Can drink alcohol"),
            )

    这样我们为USCitizen类定义了三种自定义的权限,其中第一项是codename,第二项是discription。  

    当我们定义好权限后,我们可以通过user.has_perm来判断是否具有权限

    def my_view(request):
        
    if not (request.user.is_authenticated() and request.user.has_perm('polls.can_vote')):
            
    return HttpResponse("You can't vote in this poll.")

    has_perm的参数应该是appname(packname) + . + codename

    还有一种更简便的方式,如下:
    @user_passes_test(lambda u: u.has_perm('polls.can_vote'))
    这样如果该用户没有权限,则自动跳转到/accounts/login/,也可以自定义跳转
    @user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')

    4、template中的用户验证
    Users

    {% if user.is_authenticated %}
        
    <p>Welcome, {{ user.username }}. Thanks for logging in.</p>    
    {% else %}
        
    <p>Welcome, new user. Please log in.</p>
    {% endif %}

    Permissions
    {{ perms.foo }},一个已经登陆的用户对foo的app只要有任何的权限,{{ perms.foo }}就会等于True,反之为False
    {{ perms.foo.can_vote }}, 这个很清楚了...
    实例如下:

    {% if perms.foo %}
        
    <p>You have permission to do something in the foo app.</p>
        {% if perms.foo.can_vote %}
            
    <p>You can vote!</p>
        {% endif %}
        {% if perms.foo.can_drive %}
            
    <p>You can drive!</p>
        {% endif %}
    {% else %}
        
    <p>You don't have permission to do anything in the foo app.</p>
    {% endif %}

    5、authentication backends
    Django中队用户的验证都是通过自身的模块,也可以使用其他的模块。
    默认的AUTHENTICATION_BACKENDS 是
    ('django.contrib.auth.backends.ModelBackend',)

    我们可以自己写一个不同的用户验证方式,但必须具有get_user 和authenticate方法
    如:

    from django.conf import settings
    from django.contrib.auth.models import User, check_password

    class SettingsBackend:
        
    """
        Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.

        Use the login name, and a hash of the password. For example:

        ADMIN_LOGIN = 'admin'
        ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
        
    """
        
    def authenticate(self, username=None, password=None):
            login_valid 
    = (settings.ADMIN_LOGIN == username)
            pwd_valid 
    = check_password(password, settings.ADMIN_PASSWORD)
            
    if login_valid and pwd_valid:
                
    try:
                    user 
    = User.objects.get(username=username)
                
    except User.DoesNotExist:
                    
    # Create a new user. Note that we can set password
                    # to anything, because it won't be checked; the password
                    # from settings.py will.
                    user = User(username=username, password='get from settings.py')
                    user.is_staff 
    = True
                    user.is_superuser 
    = True
                    user.save()
                
    return user
            
    return None

        
    def get_user(self, user_id):
            
    try:
                
    return User.objects.get(pk=user_id)
            
    except User.DoesNotExist:
                
    return None

    这个时候我们需要修改Setting
    AUTHENTICATION_BACKENDS = (
     'sputnik.backends.ldapBackend.LDAPBackend',
    )

    这里还有一片关于Authentication Backends的文章

    LDAP Authentication in Django with Backends

    全文结束,谈不上总结,因为缺少我的体会和心得,也谈不上翻译,因为my englishi is Poor.

    See You!!!

    注意事项:

    1.无论你是否使用了csrf,django自带的用户验证都需要使用到csrf。所以,在form的后面请加上{% csrf_token %}:

    <form method="post">{% csrf_token %}


     

    2.如果使用了ldap进行用户验证,我们还需要在settings.py文件中对ldap进行配置:

    AUTH_LDAP_SERVER_URI = "ldap://xxxxx"
    AUTH_LDAP_BIND_DN = 'cn=x,cn=x,dc=x,dc=x'
    AUTH_LDAP_BIND_PASSWORD = 'xxxxx'
    AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=x,dc=x,dc=x", ldap.SCOPE_SUBTREE, "(xxx)")


     

    ok!
  • 相关阅读:
    网络编程2018-4-23
    网络编程
    异常处理
    在Asp.net core使用配置Json创建动态目录树
    Asp.net Core中文转换成拼音
    解决Asp.Net core 控制台出现乱码的情况
    解决Asp.net Core中chtml文档中文乱码的问题
    取代Ajax.BeginForm的ajax使用方法
    将数据库模型放入到.Net Core的类库中
    如何使用Resource资源文件
  • 原文地址:https://www.cnblogs.com/chenjianhong/p/4144825.html
Copyright © 2011-2022 走看看