zoukankan      html  css  js  c++  java
  • Django——用户认证系统

    Django自带一个用户认证系统,用于处理用户账户、群组、许可和基于cookie的用户会话。

    Django的认证系统包含了身份验证和权限管理两部分。简单地说,身份验证用于核实某个用户是否合法,权限管理则是决定一个合法用户具有哪些权限。往后,‘认证’这个词同时代指上面两部分的含义。

    权限问题我们先不谈,重点先了解身份验证,最起码能实现登录、登出的基本验证,先来了解几个方法

    auth模块

    from django.contrib import auth

     django.contrib.auth 提供了很多方法,这里只简单记录三个

    authenticate()

    利用authenticate()方法,对用户进行验证。该方法通常接收username与password作为参数。如果认证信息有效,会返回一个User对象(下面会讲)。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的!

    from django.contrib.auth import authenticate
    user = authenticate(username='john', password='secret')

    login(HttpRequest, user)

    在视图中,使用认证系统的login()方法登录用户。它接收一个HttpRequest参数和一个User对象参数。该方法会把用户的ID保存在Django的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:
            login(request, user)
            # 跳转到成功页面
             ...
        else:
            # 返回错误
            ...

    logout(request)

    from django.contrib.auth import logout
    
    
    def logout_view(request):
        logout(request)
        # Redirect to a success page.

    该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

    说完这三个方法,下面看下方法的主人。

    User对象

    用户对象是Django认证系统的核心!在Django的认证框架中只有一个用户模型也就是User模型,注意这个User模型是Django自带的,和这个User模型没有任何关系的自定义用户模型是无法使用Django认证系统的功能的!

    用户模型主要有下面几个字段:

    • username
    • password
    • email
    • first_name
    • last_name

    创建用户

    要创建一个新用户,最直接的办法是使用create_user()方法:

    from django.contrib.auth.models import User
    
    user = User.objects.create_user(username='Eric',password='ericpassword',email='eric@163.com')

    如果已经启用了Django的admin站点,也可以在后台创建用户。

    修改密码

    Django默认会对密码进行加密,因此,不要企图对密码进行直接操作。

    使用set_password来修改密码:

    from django.contrib.auth.models import User
    
    u = User.objects.get(username='Eric')
    u.set_password(password="ericnewpass")
    u.save()

    check_password(password)

    不过用户要修改密码的时候,我们应该让其先输入原来的密码,验证通过后再进行修改,check_password()方法做旧密码验证,通过则返回True,所以一个基本修改密码的视图应该是:

    def set_pwd(request):
        user = request.user
        data={'status':True, 'msg': ''}
        if request.method == "POST":
            old_password = request.POST.get('old_password','')
            new_password = request.POST.get('new_password','')
            re_password = request.POST.get('re_password','')
            if user.check_password(old_password):
                if new_password:
                    if new_password == re_password:
                        user.set_password(new_password)
                        user.save()
                        return redirect('/login/')
                    else:
                        data['status']=False
                        data['msg']='两次输入密码不一致!'
                else:
                    data['status']=False
                    data['msg']='密码不能为空!'
            else:
                data['status']=False
                data['msg']='旧密码错误!'
        return render(request, 'set_pwd.html', locals())
    View Code

    后台认证与限制访问

    is_authenticated()

    每一次请求中都包含一个request.user属性,表示当前用户。如果该用户未登陆,该属性的值是一个AnonymousUser实例(匿名用户),如果已经登录,该属性就是一个User模型的实例。

    如果是真正的User对象,那么is_authenticated()返回值恒为True,用于检查用户是否已经通过了认证。在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name。

    所以,可以根据用户的登录状态,对其进行访问限制:

    1. 用户登陆后才能访问某些页面,
    2. 如果用户没有登录就访问该页面的话直接跳到登录页面
    3. 用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址
    def my_page(request):
        if not request.user.is_authenticated():
            return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

    login_requierd()

    这个是django专门用于限制访问的装饰器,因此上例可以这样简单写为

    from django,contrib.auth.decorators import login_required
    
    
    @login_required
    def my_page(request):
        ...

    若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递  当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

    AbstractUser

    上说的User对象以及方法都是Django内置的,可是如果想自己在models中创建用户表,又想用django内置的验证和限制访问等功能,怎么办呢?

    这就需要内置用户类AbstractUser,就是Django内置的一个关于用户操作的类,它极大地方便了我们对model模型中对User用户类的设计。而所谓内置用户类的本质也就是一个封装好的父类,所以使用起来是相当的方便:

    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    
    class User(AbstractUser):      # 继承AbstractUser
        mobile = models.CharField(max_length=11)

    然后在settings中添加行 AUTH_USER_MODEL = "应用名.模型类名" 

    # 指定本项目的用户模型类
    AUTH_USER_MODEL = "blog.User"

    这里只是继承了AbstractUser类,并只自定义了一个手机号的字段,而其他字段都不需再定义和设计,就完成了我们需要的模型。

    • 因为父类AbstractUser已经包含了username、password、email、first_name、last_name、last_login、date_joined、is_active 、is_staff、is_superuse这些字段,无需再次定义。
    • username、password为必选字段,其余可选。
    • 手机号字段Django中没有自带,需要我们继承AbstractUser并添加一条手机号字段即可(其他也可自己添加)。

     这样就可以使用上面的验证方式进行操作,记住创建用户要用create_user 方法!

    终日不为以思,无益,不如学也
  • 相关阅读:
    pdfobject (前台展示PDF插件)
    ERROR 19608 --- [ost-startStop-1] c.atomikos.persistence.imp.LogFileLock : ERROR: the specified log seems to be in use already: tmlog in D: ools omcatapache-tomcat-8.5.51in ransaction-logs
    文件上传下载(四) 读 txt 文本 ajaxfileupload
    1129
    centos服务器上部署项目(二) -tomcat
    Guns 打包
    centos服务器上部署项目(一) -jdk,mysql
    layui 学习笔记(四) 复杂表头前台Excel导出
    SpringCloud项目搭建(四) zuul
    sql的基本查询语句
  • 原文地址:https://www.cnblogs.com/lymlike/p/11558662.html
Copyright © 2011-2022 走看看