博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[django]总结Django中的用户权限模块
阅读量:4054 次
发布时间:2019-05-25

本文共 6422 字,大约阅读时间需要 21 分钟。

此文是总结Django官方网站里面的Document的文章 User authentication in Django

该模块由
用户(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的文章

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

See You!!!

 

原文网址:

你可能感兴趣的文章
Xpath使用方法
查看>>
移动端自动化测试-Mac-IOS-Appium环境搭建
查看>>
Selenium之前世今生
查看>>
Selenium-WebDriverApi接口详解
查看>>
Selenium-ActionChains Api接口详解
查看>>
Selenium-Switch与SelectApi接口详解
查看>>
Selenium-Css Selector使用方法
查看>>
Linux常用统计命令之wc
查看>>
测试必会之 Linux 三剑客之 sed
查看>>
Socket请求XML客户端程序
查看>>
Java中数字转大写货币(支持到千亿)
查看>>
Java.nio
查看>>
函数模版类模版和偏特化泛化的总结
查看>>
VMware Workstation Pro虚拟机不可用解决方法
查看>>
最简单的使用redis自带程序实现c程序远程访问redis服务
查看>>
redis学习总结-- 内部数据 字符串 链表 字典 跳跃表
查看>>
iOS 对象序列化与反序列化
查看>>
iOS 序列化与反序列化(runtime) 01
查看>>
iOS AFN 3.0版本前后区别 01
查看>>
iOS ASI和AFN有什么区别
查看>>