python-Django基本流程原理02-认证系统

* django认证系统 *

一. Django默认用户认证系统

Django 认证提供了实现认证(authentiaction)和授权(authorization)两种功能的用户认证系统–auth 使用的存储表auth_user
参考文档点这里

Django用户认证系统它处理用户账号、组、权限以及基于cookie的用户会话。

  • Django认证系统同时处理认证和授权:
    • 认证:验证一个用户是否可用于账号登录。
    • 授权:授权决定一个通过了认证的用户被允许做什么。
  • Django认证系统包含的内容:
    • 用户:用户模型类、用户认证。
    • 权限:标识一个用户是否可以做一个特定的任务。
    • 组:对多个具有相同权限的用户进行统一管理。
    • 密码:一个可配置的密码哈希系统,设置密码、密码校验。

主要模块:

from django.contrib import auth  //包含身份验证框架的核心及其默认模型
from django.contrib import contenttypes      //是Django内容类型系统,它允许权限与你创建的模型关联。

模块详解:

from django.contrib import auth //确保你的每个 Django 模型被创建时有四个默认权限:添加、修改、删除和查看
from django.contrib.auth.models import User //user对象
from django.contrib.auth import authenticate  // authenticate验证用户
from django.contrib.auth.models import Group //对用户进行分类的通用方法

user对象的权限操作:
django.contrib.auth.models.User” 对象有两个多对多字段:groupsuser_permissions
可以通过 user_permissions 属性将权限分配给user,或通过 permissions 属性分配给group

操作:

myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()


我们看一下基本如何使用

二. 用户认证系统实现实例

主要用到的几个方法:

  • create_user 创建用户
  • authenticate 验证登录
  • login 记住用户的登录状态
  • logout 退出登录
  • is_authenticated 判断用户是否登录
  • login_required 判断用户是否登录的装饰器

1. 创建用户:

User 对象的主要属性有 username, password, email, first_name, last_name

1.1 普通的创建用户

from django.contrib.auth.models import User
user = User.objects.create_user('yym', 'yym@yiyumo.com', 'yympassword')

~ 创建超级用户指令 python manage.py createsuperuser –username=yym --email=yym@yym.com ~

1.2 更改密码

    from django.contrib.auth.models import User
    u = User.objects.get(username='yym')
    u.set_password('new password')
    u.save()

~ 更改密码指令 python manage.py changepassword username ~

2. 验证用户

使用 authenticate()来验证用户。它使用 usernamepassword 作为参数来验证,对每个身份验证后端进行检查。如果后端验证有效,则返回一个User 对象。如果后端引发 PermissionDenied错误,将返回 None

from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
    # A backend authenticated the credentials
else:
    # No backend authenticated the credentials

3. 权限

当 INSTALLED_APPS 设置了 django.contrib.auth 时,它将确保你的每个 Django 模型被创建时有四个默认权限:添加、修改、删除和查看

3.1 创建权限

from car.models import UseCar
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

# 为车辆模型创建可发布接单的权限
content_type = ContentType.objects.get_for_model(UseCar)
permission = Permission.objects.create(
    codename='can_publish',
    name='Can Publish Posts',
    content_type=content_type,
)

3.2 权限缓存

第一次需要获取用户对象的权限检查时,ModelBackend才会缓存它们的权限

from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404

from car.models import UseCar

def user_gains_perms(request, user_id):
    user = get_object_or_404(User, pk=user_id)
    # any permission check will cache the current set of permissions
    user.has_perm('car.change_usecar')

    content_type = ContentType.objects.get_for_model(UseCar)
    permission = Permission.objects.get(
        codename='change_usecar',
        content_type=content_type,
    )
    user.user_permissions.add(permission)

    # Checking the cached permission set
    user.has_perm('car.change_usecar')  # False

    # Request new instance of User
    # Be aware that user.refresh_from_db() won't clear the cache.
    user = get_object_or_404(User, pk=user_id)

    # Permission cache is repopulated from the database
    user.has_perm('car.change_usecar')  # True

    ...

4. Web 请求的认证

4.1 web请求的验证

Django 使用 sessions 和中间件将身份验证系统挂接到请求对象中
它们在每次请求中都会提供 request.user 属性。如果当前没有用户登录,这个属性将会被设置为 AnonymousUser,否则将会被设置为 User实例。
使用 user 的属性is_authenticated来区分 用户是否已通过身份验证
使用 user 的属性is_anonymous来区分User和AnonymousUser 对象

if request.user.is_authenticated:
    user
    ...
else:
    pass

4.2 用户的登录

将已验证的用户想附加到当前会话(session)中将通过 login() 函数完成

from django.contrib.auth import authenticate, login
def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(request, username=username, password=password) //验证
    if user is not None:
        login(request, user)  //登录
        # Redirect to a success page.
        ...
    else:
        # Return an 'invalid login' error message.
        ...

4.3 用户的登出

将已验证的用户想从当前会话(session)中将删除通过 logout() 函数完成

from django.contrib.auth import logout

def logout_view(request):
    logout(request)

实际项目开发中常会遇到以下几个问题(关于这些问题之后会详细讨论):

  1. 由于默认的user通常在实际开发中并不能满足我们的需求,我们通常会继承User表进行拓展以及拓展之后用户创建时需注意密码明文等问题。
  1. 现实中 由于session的一些缺点所以一般项目中会采用基于token的鉴权机制。
    1. 服务器来说,必须存储所有在线用户的session,那么这就占用了很大的资源(cpu,内存),严重影响服务器的性能.
    2. 扩展服务器做集群,但是同时也出现了分布式session的问题
  1. django 自带的权限机制无法满足项目需求 会拓展权限设置

session机制原理图:

python-Django基本流程原理02-认证系统

token机制原理图:

python-Django基本流程原理02-认证系统

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!