乐趣区

关于python3.x:django权限认证

Django 权限认证零碎

Django 内置了弱小的用户认证 auth 模块,零碎默认应用 auth_user 表来存储用户数据。通过 from django.contrib import auth 能够导入 auth 模块,auth 模块提供了许多函数用于认证

内置办法

  • authenticate(username=’username’,password=’password’):提供了用户认证性能,即验证用户名以及明码是否正确,参数为 username 和 password;如果认证胜利(用户名和明码正确无效),便会返回一个 User 对象。
  • login(Http Request, user):实现用户登录的性能,参数为 HttpRequest 对象和一个通过认证的 User 对象。如果未登录,request.user 失去的是一个匿名用户对象 Anonymous User 对象。
  • is_authenticated():判断以后申请是否通过了认证。
  • logout(request):革除以后申请的全副 session。
  • create_user():创立新用户,至多提供用户名和用户明码,形如

    user =User.objects.create_user(username='Tom',password='test',email='tom@163.com')。
  • set_password(password):批改明码,形如 user_obj.set_password(‘test’)。
  • check_password(password):查看明码是否正确,形如 user_obj.check_password(‘test’)。
  • 另外还有一个 login_required 装璜器,通过该装璜器可能使视图函数首先判断用户是否登录。如果未登录,网页会跳转到 settings.py 设置的 LOGIN_URL 参数对应的 URL
from django.contrib.auth.decorators import login_required
@login_requireddef 
index(request):

创立自定义权限的办法

  • 通过定义数据模型减少权限,在定义模型时,能够在 Meta 中定义权限

在执行 python manage.py makemigrations 和 python manage.py migrate 命令后,就会减少一条权限,权限的名字个别是 APP_name.Permission_name 的模式。假如咱们在一个叫 myapp 的应用程序中建设以上数据模型,那么产生的权限名字就是 myapp.add_test

class test(models.Model):
  name = models.CharField(max_length=32)
  class Meta:
    permissions = [('add_test','在 test 表中减少记录的权限')]
  • 通过代码减少权限,权限是 django.contrib.auth.Permission 的实例对象,可了解为权限记录保留在 Permission 表中,它蕴含 namecodenamecontent_type 3 个字段,其中的 content_type 与数据模型相关联,能够了解为 content_type 示意一个权限在哪个应用程序中的哪个数据模型中定义
# views.py
from django.http import HttpResponse
from . import models
from django.contrib.auth.models import Permission,ContentType

# 在此处编写视图函数代码
def add_permission(request):
 content_type=ContentType.objects.get_for_model(models.test)
 # 生成一条权限记录并保留在 Permission 表中
 permission=Permission.objects.create(codename='add_test',name='在 test 表中减少记录的权限',content_type=content_type)
 return HttpResponse('ok')

案例阐明

案例利用为 au

目录构造

au
├─__init__.py
├─admin.py
├─apps.py
├─models.py
├─tests.py
├─urls.py
├─views.py
├─migrations
|     ├─0001_initial.py
|     ├─__init__.py
|     ├─__pycache__
|     |      ├─0001_initial.cpython-37.pyc
|     |      └__init__.cpython-37.pyc

views.py

# /au/views.py

from django.contrib.auth import authenticate, login
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json

# 退出 csrf 认证避免跨域报错
@csrf_exempt
def user_login(request):
  # 判断传输方式是否为 get,登录传输表单须要 post
    if request.method == 'GET':
        return HttpResponse('跳转 test_auth/login')
    else:
      # 将 post 的 body 解析出 username 与 password
        body = json.loads(request.body)
        username = body['username']
        password = body['password']
    # 通过解析传输过去的用户名与明码对用户认证
    user_obj = authenticate(username=username, password=password)
    if user_obj:
        # 让用户处于登录状态
        login(request, user_obj)
        return HttpResponse('跳转主页')
    else:
        return HttpResponse('跳转 login')

models.py

# /au/models.py

from django.db import models
# 权限认证办法
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import Permission

class authority(models.Model):
    codename = models.CharField('权限代码', max_length=32)
    url = models.CharField('URL 配置项名称', max_length=128)
    name = models.CharField('权限形容', max_length=120)

    # 重写数据模型的 save() 办法,实现了每减少一条记录,就减少一个权限
    def save(self, *args, **kwargs):
        # 获得 content_type 对象,该对象与 test_auth 中的 authority 数据模型有关联
        content_type_obj = ContentType.objects.get(app_label='au', model="authority")
        # 减少一个权限,权限代码与字段 codename 的值雷同,权限名与字段 name 的值雷同
        permission = Permission.objects.create(codename=self.codename, name=self.name, content_type=content_type_obj)
        # 调用父类的 save() 办法将数据记录保留到数据库中
        super(authority, self).save(*args, **kwargs)

    # 重写了数据模型的 delete() 办法,实现了每删除一条记录,就删除权限代码
    def delete(self, *args, **kwargs):
        content_type_obj = ContentType.objects.get(app_label='au', models='authority')
        # 取出权限对象
        permission = Permission.objects.get(codename=self.codename, content_type=content_type_obj)
        content_type = content_type_obj
        # 删除权限
        permission.delete()
        # 调用父类的 delete() 办法,删除这条记录
        # 因为以后类重写了 save 与 delete 办法,所以为了原始操作只能调用为变更过的父类办法
        super(authority, self).delete(*args, **kwargs)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '权限表'
        verbose_name_plural = verbose_name

admin.py

# /au/admin.py
from django.contrib import admin
from . import models


# 定义默认 admin 页面展现字段
class AuthorityAdmin(admin.ModelAdmin):
    list_display = ('codename', 'url', 'name')


admin.site.register(models.authority, AuthorityAdmin)
退出移动版