Django 验证系统

1.介绍

 

1.1. User 对象

(1)创建超级管理员:

python manage.py createsuperuser

(2)创建用户:

from django.contrib.auth.models import User

user = User.objects.create_user('zzj', 'zzj@qq.com', '135246')

(3)更改密码

通过命令:

python manage.py changepassword *username*

通过函数:

from django.contrib.auth.models import User

u = User.objects.get(username='john')
u.set_password('new password')
u.save()

1.2.权限

User 对象有两个多对多字段:groups 和 user_permissions

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()

(1)默认权限

        当 INSTALLED_APPS 设置了 django.contrib.auth ,执行python manage.py migrate时生成6个表:

        并且,每个 Django 模型在执行python manage.py migrate时,会有四个默认权限:添加、修改、删除和查看。

(2)创建权限

        例如,为 BlogPost 模型创建 can_publish 权限:

from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
    codename='can_publish',
    name='Can Publish Posts',
    content_type=content_type,
)

(3)分配权限

        通过user_permissions将权限分配给 User,或通过 permissions 属性分配给 Group

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

       

(4)权限缓存

        在第一次需要获取用户对象的权限检查时, 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 myapp.models import BlogPost

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('myapp.change_blogpost')

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

    # Checking the cached permission set
    user.has_perm('myapp.change_blogpost')  # 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('myapp.change_blogpost')  # True

1.3.认证

        Django 使用 sessions 和中间件将身份验证系统挂接到请求对象中。

(1)验证用户

        使用 authenticate() 来验证用户。它使用 username 和 password 作为参数来验证,对每个身份验证后端( authentication backend ` )进行检查。

        如果后端验证有效,则返回一个:class:`~django.contrib.auth.models.User 对象。如果后端引发 PermissionDenied 错误,将返回 None。

from django.contrib.auth import authenticate

user = authenticate(request, username=username, password=password)

(2)添加session 

        使用login(),在 session 中保存用户的ID

(3)登出

        如果已经通过 django.contrib.auth.login() 登录的用户想退出登录,可以在视图中使用 django.contrib.auth.logout() 。需要传入 HttpRequest 对象,并且该函数不会返回值。

def logout_view(request):
    from django.contrib.auth import logout
    logout(request)
    return redirect("/test_auth/login/")

        并且会自动清除session

(4)限制对未登录用户的访问

        原始方法就是检查request.user.is_authenticated,并重定向到登录页面,或者错误页。

        快捷方式可通过login_required 装饰器,login_required(redirect_field_name='next', login_url=None)

       

        未登录时访问,会重定向到 login_url,并传递路径到redirect_field_name的值中,redirect_field_name默认为next,可自定义;如果没有指定login_url,也可在settings.LOGIN_URL关联登录视图。

         基于类的视图,可使用LoginRequiredMixin,且需放在继承列表的最前面。

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    login_url = '/login/'
    redirect_field_name = 'redirect_to'

(5)限制权限的访问

        permission_required() 装饰器

from django.contrib.auth.decorators import permission_required

@permission_required('polls.add_choice', login_url='/loginpage/')
def my_view(request):
    ...

        和 login_required() 装饰器一样, login_url 默认是:setting:settings.LOGIN_URL 。

        如果有 raise_exception 参数,那么装饰器将引发 PermissionDenied 错误,提示 the 403 (HTTP Forbidden) view 而不是跳转到登录页面。

        如果想使用 raise_exception 但也想给用户登录的机会,那需要添加 login_required() 装饰器:

from django.contrib.auth.decorators import login_required, permission_required

@login_required
@permission_required('polls.add_choice', raise_exception=True)
def my_view(request):
    ...

        基于类的视图,可使用PermissionRequiredMixin

from django.contrib.auth.mixins import PermissionRequiredMixin

class MyView(PermissionRequiredMixin, View):
    permission_required = 'polls.add_choice'
    # Or multiple of permissions:
    permission_required = ('polls.view_choice', 'polls.change_choice')

(6)限制其他条件的访问

        例如用户是否有特定域名的邮箱,调用 user_passes_test 装饰器,当调用返回 False 时会执行重定向:user_passes_test(test_func, login_url=None, redirect_field_name='next')

from django.contrib.auth.decorators import user_passes_test

def email_check(user):
    return user.email.endswith('@example.com')

@user_passes_test(email_check)
def my_view(request):
    ...

        基于类的视图,可UserPassesTestMixin

from django.contrib.auth.mixins import UserPassesTestMixin

class MyView(UserPassesTestMixin, View):

    def test_func(self):
        return self.request.user.email.endswith('@example.com')

(7)密码更改时,会话失效

        修改了密码,如果不调用update_session_auth_hash(request, user),则会自动退出登录。

调用后,则会自动更新 session表,不会自动注销。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值