本章着重总结Django的用户与认证
一. cookies
http(s)本身是无状态的,当前请求和下次请求之前无任何状态保持,为了存储状态,首先应运而生的是cookies。在Django中,每个request都包含了一个COOKIES对象,可以像字典一样使用它。
虽然cookies能解决了状态保持问题,但是引出了其他问题:
a. 浏览器不保证会存储,是否接受cookies在浏览器端用户可以控制;
b. cookies在浏览器中是可清除的,不可存储重要信息,否则可能发生不可恢复的问题;
c. http是明文传输,因此中间人容易拦截获取cookies并使用,不安全,容易被篡改;
二. session
为了解决cookies所带来的问题,session(会话)已然成为了web开发青睐的手段。在Django中,自带session框架解决了这个需求,存取每个用户的任意数据,该数据可存储在服务器端或者以文件等方式存储。
在Django中,sessions 功能是通过一个中间件(middleware)和一个模型(model)来实现的,为了使用session功能,需要确认以下(默认情况是打开):
a. 确认MIDDLEWARE(中间件) django.contrib.sessions.middleware.SessionMiddleware
被添加在MIDDLEWARE
b. 确认 session app(系统) django.contrib.sessions
被添加在INSTALLED_APPS
激活后,每个httpRequest都有一个session属性,是一个字典对象,每个session对象都是由一个随机的32位哈希串来标识
由于session是依赖cookies来设计的,session的有效期等需要进行一些设置,比如关闭浏览器失效还是有效期一个星期失效等,常用的如下:
1. SESSION_ENGINE
设置引擎,决定session保存在哪里,默认数据库
2. SESSION_COOKIE_NAME
Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
3. SESSION_COOKIE_PATH
保存的路径
4. SESSION_COOKIE_DOMAIN
保存的域名
5. SESSION_COOKIE_SECURE
是否https传输cookie
6. SESSION_COOKIE_AGE
cookie的有效期
7. SESSION_EXPIRE_AT_BROWSER_CLOSE
是否关闭浏览器就失效
8. SESSION_SAVE_EVERY_REQUEST
是否每次请求都保存Session,默认修改之后才保存
三. 用户、认证与授权
auth模块(app)是Django提供的标准认证与授权系统,主要做2件事:
a. 认证用户,主要比对系统中是否存在该用户
b. 检查权限,主要确定用户是否有某些操作,即被授权某些操作
默认情况,应用到的中间件django.contrib.auth.middleware.AuthenticationMiddleware
和app 系统django.contrib.auth
是打开的。User模型是auth模块中维护的用户信息关系模型。主要字段用户名、密码、邮箱等,可在auth/models.py
中查看具体,继承关系如下
User----继承----> AbstractUser---->AbstractBaseUser和PermissionsMixin
其中AbstractBaseUser定义了对象字段和操作数据表的API,PermissionsMixin定义了权限相关内容
本次建系统的过程中,用户内置的User不够满足需求,采用了扩展AbstractUser的方式,怎么创建适合的User模型得看需求,这篇文章已经说得很清楚,可参考:http://www.cnblogs.com/yxi-liu/p/8684504.html
用户的认证
authenticate(),通过用户名称和密码进行用户的认证
login(request, user),该函数接受一个 HttpRequest 对象和一个 User 对象作为参数并使用Django的会话( session )框架把用户的ID保存在该会话中
logout(),实际就是清除了session中的user信息,它接受一个HttpRequest对象并且没有返回值,所以,因为没有返回值,需要返回一个页面。
from django.contrib.auth import login,logout,authenticate
user=authenticate(username=userName, password=password)
if user is not None and user.is_active:
login(request, user)#认证通过后,调用login方法,主要是设置session
说完了用户的问题,接下来说说权限与组
使用auth 原生或扩展的User,执行完migrate
和makemigrations
,即python3 manage.py migrate auth``python3 manage.py makemigrations auth
后,会在数据库中生成3个表
auth_group:组,包括id和name
auth_group_permission: 组权限,包括id、group_id、permission_id
auth_permission: 权限信息,包括name、content_type_id和codename字段,codename主要是使用权限方法传入的参数,content_type_id与模型相关
permission总是与model对应的,如果一个object不是model的实例,我们无法为它创建
在创建model时,可通过元类的方式自定义权限
class Meta:
permissions =
(
("view_server", "can view server"),//(codename,name)
("change_server_status", "Can change the status of server"),
)
或者通过脚本的方式设置权限
#假设model为blog,app为blogs
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import Permission
content_type=ContentType.objects.get_for_model(blog)
permissions=Permission.objects.create(codename="can_edit_blog",name="edit blog ",content_type=content_type)
#以上权限可通过user_permissions或permission属性的Groups分配给一个User对象
user.user_permissions.add(permissions)
group=Group.objects.get(name='only_view_person')
user.groups.add(group)
#以上只是举例为用户添加权限,其他方法有clear()、set()、remove()
验证权限
user.has_perm('blogs.can_edit_blog')#或者使用装饰器@permission_required("blogs.can_edit_blog")装饰函数
#页面验证权限
{%if perms.blogs.can_edit_blog%}