Django中用户权限模块
Django中用户权限模块
1 auth模块
auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理。
auth可以和admin模块配合使用, 快速建立网站的管理系统。
在INSTALLED_APPS中添加'django.contrib.auth'使用该APP, auth模块默认启用。
2 User属性与方法
(1) 属性
User是auth模块中维护用户信息的关系模式(继承了models.Model), 数据库中该表被命名为auth_user.
参照后续源码更清楚的了解User类继承的属性与方法.这里只是展示一部分.
该数据表在数据库中:
'auth_user'
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"password" varchar(128) NOT NULL, "last_login" datetime NULL,
"is_superuser" bool NOT NULL,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL,
"email" varchar(254) NOT NULL,
"is_staff" bool NOT NULL,
"is_active" bool NOT NULL,
"date_joined" datetime NOT NULL,
"username" varchar(30) NOT NULL UNIQUE
一般当建立关联表时需要与User建立关联,则需要导入使用,比如建议OneToOne联系
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User) #建立关联到User
blog = models.CharField(maxlength=128, blank=True)
location = models.CharField(maxlength=128, blank=True)
occupation = models.CharField(maxlength=64, blank=True)
(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):给某用户发送邮件
例如创建一个superuser装饰器:
#登录用户必须为超级用户,只能在类中使用
def superuser_required(func):
def _wrapper(self,request,*args,**kwargs):
#User中包含了is_superuser属性
if not request.user.is_superuser:
#定义的未登录函数 not_authenticated()
return not_authenticated()
return func(self,request,*args,**kwargs)
return _wrapper
这里设置superuser当然也可以自己设置不同权限的装饰器,这样代码更加简单!!
3 User常见的用法
(1) 新建用户
user = User.objects.create_user(username, password)
user.save() #保存数据库
auth模块不存储用户密码明文而是存储一个Hash值
(2) 验证登录
from django.contrib.auth import login
username = request.POST['username']
password = request.POST['password']
#login不进行认证,也不检查is_active标志位, 一般和authenticate配合使用:
user = authenticate(username=username, password=password)
if not user:
if user.is_active:
return HttpResponse(json.dumps({
'error':'用户名或者密码错误'
}))
login(request,user)
login向session中添加SESSION_KEY, 便于对用户进行跟踪.
首先我们要验证这个用户,然后再登陆,登陆成功后,我们可以通过request.user 来得到当前登陆的用户对象
(3) 退出登录
logout会移除request中user信息,并刷新session,清空cookie中sessionid
from django.contrib.auth import logout
def logout_view(request):
logout(request)
(4) 限制非法用户访问
普通做法通过 request.user.is_authenticated()判定,返回重定向login登录界面
from django.http import HttpResponseRedirect
def my_view(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login.html/')
这种方法会造成重复判定问题
简单做法采用装饰器语法糖搞定,django中封装了login_required
from django.contrib.auth.decorators import login_required
@login_required #过滤掉非登录用户
def my_view(request):
#限定为合法用户访问
这样当你访问my_view的时候,就需要用户需要通过验证,不通过可以重定向来解决
4 Group用户组
django.contrib.auth.models.Group定义了用户组的模型, 每个用户组拥有id和name两个字段, 该模型在数据库被映射为auth_group数据表。
User对象中有一个名为groups的多对多字段, 多对多关系由auth_user_groups数据表维护。Group对象可以通过user_set反向查询用户组中的用户。
# 创建create
group = Group.objects.create(name=group_name)
group.save()
#add
用户加入用户组user.groups.add(group)或group.user_set.add(user)
#remove
用户退出用户组user.groups.remove(group)或group.user_set.remove(user)
5 Permission
Django的auth系统提供了模型级的权限控制, 即可以检查用户是否对某个数据表拥有增(add), 改(change), 删(delete)权限,但无法检查用户对某一篇博文是否拥有管理权限。
user.has_perm('blog.add_article')
user.has_perm('blog.change_article')
user.has_perm('blog.delete_article')
user.has_perm方法用于检查用户是否拥有操作某个模型权限,若拥有权限则返回True。仅是进行权限检查, 即是用户没有权限它也不会阻止程序员执行相关操作。
permission_required修饰器可以代替has_perm并在用户没有相应权限时重定向到登录页或者抛出异常。
# permission_required(perm[, login_url=None, raise_exception=False])
#给blog中article添加权限,装饰器之后更加简单
@permission_required('blog.add_article')
def post_article(request):
pass
6 管理用户权限
User和Permission通过多对多字段user.user_permissions关联,在数据库中由auth_user_user_permissions数据表维护,可以执行添加权限,删除权限,清空权限.
7 User继承的父类
User先继承AbstractUser类,该类的基类为AbstractBaseUser,有兴趣的了解下,可以更深入的发现User类的功能
附上User继承类AbstractUser类的基类AbstractBaseUser的源码:
class AbstractBaseUser(models.Model):
'''
常见的子类User继承的属性:
password 密码
last_login 最后登录
is_active 是否在线
常见定义的方法:
save 保存
is_authenticated 登录验证
set_password 设置密码
check_password 检查密码
'''
password = models.CharField(_('password'), max_length=128)
last_login = models.DateTimeField(_('last login'), blank=True, null=True)
is_active = True
REQUIRED_FIELDS = []
class Meta:
abstract = True
def get_username(self):
return getattr(self, self.USERNAME_FIELD)
def __init__(self, *args, **kwargs):
super(AbstractBaseUser, self).__init__(*args, **kwargs)
self._password = None
def __str__(self):
return self.get_username()
def clean(self):
setattr(self, self.USERNAME_FIELD, self.normalize_username(self.get_username()))
def save(self, *args, **kwargs):
super(AbstractBaseUser, self).save(*args, **kwargs)
if self._password is not None:
password_validation.password_changed(self._password, self)
self._password = None
def natural_key(self):
return (self.get_username(),)
@property
def is_anonymous(self):
"""
Always return False. This is a way of comparing User objects to
anonymous users.
"""
return CallableFalse
@property
def is_authenticated(self):
"""
Always return True. This is a way to tell if the user has been
authenticated in templates.
"""
return CallableTrue
def set_password(self, raw_password):
self.password = make_password(raw_password)
self._password = raw_password
def check_password(self, raw_password):
"""
Return a boolean of whether the raw_password was correct. Handles
hashing formats behind the scenes.
"""
def setter(raw_password):
self.set_password(raw_password)
# Password hash upgrades shouldn't be considered password changes.
self._password = None
self.save(update_fields=["password"])
return check_password(raw_password, self.password, setter)
def set_unusable_password(self):
# Set a value that will never be a valid hash
self.password = make_password(None)
def has_usable_password(self):
return is_password_usable(self.password)
def get_full_name(self):
raise NotImplementedError('subclasses of AbstractBaseUser must provide a get_full_name() method')
def get_short_name(self):
raise NotImplementedError('subclasses of AbstractBaseUser must provide a get_short_name() method.')
def get_session_auth_hash(self):
"""
Return an HMAC of the password field.
"""
key_salt = "django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash"
return salted_hmac(key_salt, self.password).hexdigest()
@classmethod
def get_email_field_name(cls):
try:
return cls.EMAIL_FIELD
except AttributeError:
return 'email'
@classmethod
def normalize_username(cls, username):
return unicodedata.normalize('NFKC', force_text(username))
User继承类AbstractUser类的源码:
class AbstractUser(AbstractBaseUser, PermissionsMixin):
'''
继承该类常见属性有:
username 用户名
first_name 姓
last_name 名
email 邮箱
'''
username_validator = UnicodeUsernameValidator() if six.PY3 else ASCIIUsernameValidator()
username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists."),
},
)
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('email address'), blank=True)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this admin site.'),
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'
),
)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = UserManager()
EMAIL_FIELD = 'email'
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
abstract = True
def clean(self):
super(AbstractUser, self).clean()
self.email = self.__class__.objects.normalize_email(self.email)
def get_full_name(self):
"""
Returns the first_name plus the last_name, with a space in between.
"""
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
"Returns the short name for the user."
return self.first_name
def email_user(self, subject, message, from_email=None, **kwargs):
"""
Sends an email to this User.
"""
send_mail(subject, message, from_email, [self.email], **kwargs)
注: 1 权限部分参考了原文:http://www.cnblogs.com/Finley/p/5575305.html 非常感谢!!
2 后续我会提供: 注册/验证/登录/注销封装好的类,感谢大家阅读!!!
Django中用户权限模块的更多相关文章
- 1205 CSRF跨站请求与django中的auth模块使用
目录 今日内容 昨日回顾 基于配置文件的编程思想 importlib模块 简单代码实现 跨站请求伪造csrf 1. 钓鱼网站 如何实现 模拟该现象的产生 2. 解决问题 解决 {% csrf_toke ...
- Django中的权限系统
Django中已经为我们设置好了基本的权限系统,在定义好model同步数据库后,在每个库下面都会有一张 'auth_permission' 表.该表里面记录了每条权限的描述(name字段,can do ...
- Django RBAC用户权限设计方案
RBAC基于用户权限系统设置方案 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干 ...
- Docker容器中用户权限管理
在Linux系统中有一部分知识非常重要,就是关于权限的管理控制:Linux系统的权限管理是由uid和gid负责,Linux系统会检查创建进程的uid和gid,以确定它是否有足够的权限修改文件,而非是通 ...
- 在Django中使用logging模块
一.Django logging配置 1.在setting.py中配置 # 日志文件存放路径 BASE_LOG_DIR = os.path.join(BASE_DIR, "log" ...
- Window上python开发--4.Django的用户登录模块User
Android系统开发交流群:484966421 OSHome. 微信公众号:oshome2015 在搭建站点和web的应用程序时,用户的登录和管理是差点儿是每一个站点都必备的. 今天主要从一个实例了 ...
- django中的auth模块以及分页器
1.auth模块 auth模块是Django提供的标准权限管理系统,可以提供用户身份认证,和权限管理 auth可以和admin模块配合使用, 快速建立网站的管理系统 在INSTALLED_APPS中添 ...
- Django 中使用权限认证
权限认证 权限概念 """ 在实际开发中,项目中都有后台运营站点,运营站点里面会存在多个管理员, 那么不同的管理员会具备不同的任务和能力,那么要实现这样的管理员功能,那么 ...
- 用户权限模块之spring security
准备工作:数据库采用mysql(5.6及以上) CREATE TABLE `auth_system` ( `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'I ...
随机推荐
- 公司内网搭建代理DNS使用内网域名代替ip地址
企业场景 一般在企业内部,开发.测试以及预生产都会有一套供开发以及测试人员使用的网络环境.运维人员会为每套环境的相关项目配置单独的Tomcat,然后开放一个端口,以 IP+Port 的形式访问.然而随 ...
- windows10不能修改hosts解决方案(亲测)
hosts文本解释: 有时候我们要破解一些软件与服务器通讯,所以通常都需要更改Hosts文件来达到目的,XP系统可以直接修改保存,但是Win10系统却提示没有权限去修改,那么我们要怎样办呢,我们修改的 ...
- Ubuntu 16.04开启SSH服务
安装: sudo apt-get install openssh-server 启动: sudo service ssh start 查询服务启动状态: sudo ps -e | grep ssh 或 ...
- codeforces——961C. Chessboard
本文是博主原创文章,未经允许不得转载. 我在csdn也同步发布了此文,链接 https://blog.csdn.net/umbrellalalalala/article/details/7989225 ...
- JavaScript打开新窗口被拦截问题
新窗口打开页面,一个很常用的效果,至于代码,一般第一反应都是这么写: window.open(url); 但是主流的浏览器都会拦截这种效果(可能这些年弹窗广告太多,如果浏览器不拦截,用户受不了) ...
- JAVA库函数总结【持续更新】
生成随机数: Math.random()是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值. Random rand = newRandom(); rand.nextInt( ...
- 洛谷 P1490 解题报告
P1490 买蛋糕 题目描述 野猫过生日,大家当然会送礼物了(咳咳,没送礼物的同志注意了哈!!),由于不知道送什么好,又考虑到实用性等其他问题,大家决定合伙给野猫买一个生日蛋糕.大家不知道最后要买的蛋 ...
- Java 算法(二)
[程序9] 题目:一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程找出1000以内的所有完数 //第一种public class A09 {publi ...
- vue国际化高逼格多语言
## 1.NPM 项目安装 ``` cnpm i vue-i18n ``` ## 2.使用方法 ``` /* 国际化使用规则 */ import Vue from 'vue' import VueI1 ...
- Java 面试知识点解析(三)——JVM篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...