zoukankan      html  css  js  c++  java
  • Django自带表User认证详解


    认证登陆(附方法实现代码,百度网盘拉取即可下载,激活码:gqt1)

    在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中; 如果用户存在于数据库中,然后再验证用户输入的密码,这样一来就要自己编写大量的代码。 事实上,Django已经提供了内置的用户认证功能。
    在使用"python manage.py makemigrationss"和"python manage.py migrate"迁移完成数据库之后 根据配置文件settings.py中的数据库段生成的数据表中已经包含了6张进行认证的数据表,分别是 auth_user auth_group auth_group_permissions auth_permission auth_user_groups auth_user_user_permissions 进行用户认证的数据表为auth_user 要使用Django自带的认证功能,首先要导入auth模块

    Django从开始就带有一个用户认证系统;它处理用户账号、组、权限以及基于cookie的用户会话。   
    Django认证系统同时处理认证和授权。简单地讲,认证验证一个用户是否它们声称的那个人,
    授权决定一个通过了认证的用户被允许做什么。这里的词语“认证”同时指代这两项任务。
    
    认证系统包含: 
    用户。
    权限:二元(是/否)标志指示一个用户是否可以做一个特定的任务。
    组:对多个用户运用标签和权限的一种通用的方式。

    我们先来看看User表的结构:
    1,is_authenticated()
      这个认证的方法,验证是否通过,也就是通过用户名和密码判断该用户是否存在。 2,is_anonymous()
      方法也常用,判断是否为匿名用户,如果你已经login,则这个方法返回始终为false。 3,is_staff   是否为staff身份,布尔值。拥有staff身份的用户可以登录django的admin后台 4,is_superuser   是否是superuser身份,布尔值。拥有该身份的用户将能够登录admin后台,并拥有所有注册模型的管理权限。 5,last_login   用户最后登录的时间。 6,date_joine   用户创建的时间。


    接下来我们看具体的代码方法实现:

    1,创建用户

    第一种使用manage.py创建用户,这创建的是一个超级用户:

    python manage.py createsuperuser   #创建超级用户
    python manage.py changepassword admin #修改超级用户密码

     第二种是创建普通用户,

    from django.contrib.auth.models import User
    
    User.objects.create_user(username=username, password=password2)  #User对象属性:username,password为必填项password用哈希算法保存到数据库中   

    2,更改密码

    from django.contrib.auth.models import User
    
    u = User.objects.get(username='dkey')
    
    # set_password函数,设置密码;
    u.set_password('123456')
     
    # check_password函数,检查密码;
    u.check_password('123456')
    True
     
    # save函数,保存密码;
    u.save()

    3,认证用户

    from django.contrib.auth import authenticate
    user
    = authenticate(username='dkey', password='123456') if user is not None: # the password verified for the user if user.is_active: print("User is valid, active and authenticated") else: print("The password is valid, but the account has been disabled!") else: # the authentication system was unable to verify the username and password print("The username and password were incorrect.")

    4,登录

    如果你有一个认证了的用户,你想把它附带到当前的会话中 – 这可以通过login()函数完成。

    从视图中登入一个用户,请使用login()。它接受一个HttpRequest对象和一个User对象。login() 使用Django的session框架来用户的ID保存在session中。

    注意,任何在匿名会话中设置的数据都会在用户登入后的会话中都会记住。

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

    login()做的事情就有给该用户设置session信息的,保证后面验证用户是否认证通过。

    5,登出

    若要登出一个已经通过django.contrib.auth.login()登入的用户,可以在你的视图中使用django.contrib.auth.logout()

    它接收一个HttpRequest对象且没有返回值。例如:

    def logout_view(request):#登出
        logout(request)     #当调用该函数时,当前请求的session信息全部被清除,即使当前用户没有登陆,调用该函数也不会报错。   
        return redirect('/')

    注意,即使用户没有登入,login()也不会抛出任何错误。

    6,只允许登录的用户访问

    from django.conf import settings
    from django.shortcuts import redirect
     
    def my_view(request):
        if not request.user.is_authenticated():
            return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
        else:
            do_something()

    使用login_required装饰器 

    举个例子比如用户没有登录的情况下访问用户中心:

    from django.utils.decorators import method_decorator  #类装饰方法
    from django.contrib.auth.decorators import login_required
    class UserCenterInfoView(View):
        @method_decorator(login_required)
        def get(self,request):
            return render(request,'centerinfo.html')

    注:上面是个个人中心的视图函数,因为需要用到装饰器,所有我这里需要用到类装饰器的方法,在稍后我会讲解类装饰器的用法

    login_required 这个方法 接收两个参数,

    1,login_url='/login/'      这个参数表示用户被重定向登录页面  当然也可以不进行制定  ,我们在settings中定义

    #如果后台login_required 装饰器未指定跳转路径,这里需要定义下
    LOGIN_URL = '/login/'

    2,redirect_field_name='next'   这个方法值默认是next,它代表登录成功后需要跳转的页面,当然我们可以重写覆盖next

    下面登录函数实现后台控制用户登录对页面访问的权限

    class LoginView(View):
        '''
        登录
        '''
        def get(self,request):
            return render(request,'login.html')
    
        def post(self,request):
            if request.user.is_authenticated():
                return HttpResponse('该用户已登录,请勿重复登录')
    
            username = request.POST.get('username')
            pwd = request.POST.get('pwd')
            user = authenticate(username=username,password=pwd)
            if user is not None:
                if user.is_active:
                    login(request,user)
                    request.session['username'] = user.username
                    next = request.GET.get('next')         #主要这里 ,捕获next 值是否存在
                    if next is None:
                        return redirect(reverse('demo:index'))
                    else:
                        return redirect(next)
            else:
                return render(request,'login.html',{'msg':'用户名或密码错误'},status=400)

    7,引用user模型

    不要直接引用User,而应该使用django.contrib.auth.get_user_model()引用User模型。(下面是关联User表的方法)

    from django.conf import settings
    from django.db import models
    
    class UserInfo(models.Model):
        auther = models.ForeignKey(settings.AUTH_USER_MODEL)  #这个参数setting里不需要定义的

    view视图中我们这要调用:

    from django.contrib.auth import get_user_model
    User = get_user_model()

    8,重写user表,增加字段设置

    models中:

    from django.contrib.auth.models import AbstractUser
    class User(AbstractUser): mobile = models.CharField(max_length=11,unique=True,verbose_name='手机号')

    并且在setting中进行 设置:

    AUTH_USER_MODEL = 'users.User'   #应用表 + 表名

    这样就可以给django认证的user表 增加字段

    9,django认证保持登录状态机制

    Django引申出了session.login,就是生成session。对应的django在数据库中自动生成了django_session表用于存放用户session。

    表字段session_key就是浏览器中的session_id,

    session_data是对账号密码等信息做了加密的,expire_date是过期时间;在setting中可设置过期时间。

    这个session_id是怎么做到转换回账号密码等信息的?因为我们在后台是可以直接request.user的。

    INSTALLED_APPS = [
        'django.contrib.sessions', 
    ]

    这个app是会对我们每次request和respone的请求做拦截的,拦截浏览器过来的时候就会在里面找到我们的session_id。

    然后来数据表查询session_data并解密,我们response的时候他也会主动加上session_id。

    cookies

     

     session表

     

    10,类装饰器用法

    1,为全部请求方法添加装饰器

    from django.utils.decorators import method_decorator 
    
    @method_decorator(my_decorator, name='dispatch')
    class DemoView(View):
        def get(self, request):
            print('get方法')
            return HttpResponse('ok')
    
        def post(self, request):
            print('post方法')
            return HttpResponse('ok')

    2,为特定请求方法添加装饰器

    @method_decorator(my_decorator, name='get')
    class DemoView(View):
        def get(self, request):
            print('get方法')
            return HttpResponse('ok')
    
        def post(self, request):
            print('post方法')
            return HttpResponse('ok')

    3, 为特定请求方法添加装饰器

    class DemoView(View):
    
        @method_decorator(my_decorator)  # 为get方法添加了装饰器
        def get(self, request):
            print('get方法')
            return HttpResponse('ok')
    
        @method_decorator(my_decorator)  # 为post方法添加了装饰器
        def post(self, request):
            print('post方法')
            return HttpResponse('ok')
    
        def put(self, request):  # 没有为put方法添加装饰器
            print('put方法')
            return HttpResponse('ok')
  • 相关阅读:
    ASP.NET和PHP全面对比
    GridView事件DataBinding,DataBound,RowCreated,RowDataBound区别及执行顺序分析
    OA、CRM、ERP之间的区别和联系是什么?
    C#继承
    对软件项目管理的几点认识
    冒泡
    经典排序算法
    asp.net遍历页面中所有TextBox,并赋值为String.Empty的方法
    String.Format用法
    frame和iframe
  • 原文地址:https://www.cnblogs.com/lvye001/p/10141365.html
Copyright © 2011-2022 走看看