• Title


    auth模块

    之前我们在进行用户登录验证的时候,都是自己写代码,接收用户提交的数据,然后去数据库取数据进行匹配验证,其实Django已经给我们提供了内置的用户认证功能。不信的话你可以打开models.py,新建一个model类,然后执行python manage.py makemigrationss和python manage.py migrate,可以发现数据库中除了自己建的表之外,还有如下表:

    • auth_user
    • auth_group
    • auth_group_permissions
    • auth_permission
    • auth_user_groups
    • auth_user_user_permissions
      以上6张表都是用于认证的,其中auth_user表是用于用户认证的
      使用Django自带的认证功能,需要导入auth模块
    from django.contrib import auth
    

    auth里面封装了许多方法,用的最多的有三个


    ## authenticate方法 提供了用户认证,即验证用户名以及密码是否正确,一般需要username password两个关键字参数

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

    使用Pycharm新建项目authDemo, 执行2个命令,生成django需要的表

    python manage.py makemigrations
    python manage.py migrate
    

    使用命令行创建一个超级用户

    python manage.py createsuperuser
    

    会提示输入用户名、邮箱、密码等,<font color='#ff0000'注意输入密码时是看不见的,光标也不会移动,输入完回车就行!
    打开auth_user表,可以可以看到多了一条记录,其中密码是加密存储的

    修改urls.py,增加路径

    from django.contrib import admin
    from django.urls import path
    from app1 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.login),
        path('index/', views.index),
    ]
    
    

    修改views.py,增加视图函数 ```python from django.shortcuts import render, HttpResponse, redirect from django.contrib import auth # Create your views here.

    def login(request):
    if request.method == 'POST':
    user = request.POST.get('user')
    pwd = request.POST.get('pwd')
    # 用户认证成功,返回user对象,否则返回None
    ret = auth.authenticate(username=user, password=pwd)
    print(ret)
    print(type(ret))
    print(ret.dict)
    if ret:
    return redirect('/index/')
    return render(request, 'login.html')

    def index(request):
    return render(request, 'index.html')

    <br>
    在templates新建文件login.html和index.html
    login.html
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    
    <form action="" method="post">
        {% csrf_token %}
        <label for="user">用户名</label>
        <input type="text" name="user" id="user">
        <label for="pwd">密码</label>
        <input type="password" name="pwd" id="pwd">
        <input type="submit">
    </form>
    
    </body>
    </html>
    
    

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <h3>个人主页</h3>
    
    </body>
    </html>
    
    

    访问登录页面

    登录成功跳转道index页面

    查看控制台输出

    liu
    <class 'django.contrib.auth.models.User'>
    {'_state': <django.db.models.base.ModelState object at 0x0000026910303518>, 'id': 2, 'password': 'pbkdf2_sha256$120000$1YA8aSwnUOkF$6B0WD0O/pplS1jw9MZCcehBm4U/qRu1ps3qEWIsD6oY=', 'last_login': None, 'is_superuser': True, 'username': 'liu', 'first_name': '', 'last_name': '', 'email': 'abc@qq.com', 'is_staff': True, 'is_active': True, 'date_joined': datetime.datetime(2019, 3, 28, 11, 39, 17, 253175, tzinfo=<UTC>), 'backend': 'django.contrib.auth.backends.ModelBackend'}
    

    ## login方法 login的语法为`login(HttpResponse, user)`,其接收一个HttpResponse对象,以及换一个认证的User对象,作用是使用django的session框架给某个已认证的用户加上sessionid等信息

    修改views.py

    from django.shortcuts import render, HttpResponse, redirect
    from django.contrib import auth
    # Create your views here.
    
    
    def login(request):
        if request.method == 'POST':
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            # 用户认证成功,返回user对象,否则返回None
            user = auth.authenticate(username=user, password=pwd)
            # print(user)
            # print(type(user))
            # print(user.__dict__)
            if user:
                # 登录,注册session,同时会把user封装道request中
                auth.login(request, user)
                return redirect('/index/')
        return render(request, 'login.html')
    
    
    def index(request):
        # request.user是当前用户,如果没有登录则默认是AnonymousUser
        print(request.user)
        print(request.user.id)
        print(request.user.username)
        print(request.user.password)
        return render(request, 'index.html')
    

    直接访问index
    报错

    控制台输出

    AnonymousUser
    None
    (报错信息忽略)
    

    request.user 默认是一个匿名对象,auth_user表的所有字段对应的值,都是空的
    登录成功后,查看控制台输出

    liu
    2
    liu
    pbkdf2_sha256$120000$1YA8aSwnUOkF$6B0WD0O/pplS1jw9MZCcehBm4U/qRu1ps3qEWIsD6oY=
    
    

    注意,request.user是全局变量,可以在任意代码中运用那么它是怎么实现的呢,答案是利用中间件实现的,我们来看一下settings里面的配置

    红色方框里面的就是认证的中间件
    auth.login(request, user)这句话执行之后,就注册session,产生了一个全局变量


    上面的例子里没有登录就可以访问主页是不对的,应该加入判断
    修改index视图函数 ```python def index(request): # request.user是当前用户,如果没有登录则默认是AnonymousUser # print(request.user) # print(request.user.id) # print(request.user.username) # print(request.user.password)
    user_id = request.user.id
    print(user_id)
    name = request.user.username
    if user_id:
        return render(request, 'index.html', {'name': name})
    return redirect('/login/')
    
    <br>
    修改index.html
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <h3>个人主页</h3>
    
    <h3>Hi! {{ name }}</h3>
    
    </body>
    </html>
    
    

    logout方法

    logput为注销,语法为auth.logout(request)

    修改urls.py,增加路径logout

    from django.contrib import admin
    from django.urls import path
    from app1 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.login),
        path('index/', views.index),
        path('logout/', views.logout),
    ]
    
    

    修改views.py,增加logout视图函数

    def logout(request):
        auth.logout(request)  # 清除cookie和session
        return redirect('/login/')
    
    

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


    修改index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <h3>个人主页</h3>
    
    <h3>Hi! {{ name }}</h3>
    
    <a href="/logout/">注销</a>
    
    </body>
    </html>
    
    

    刷新页面

    点击注销,跳转到了登录界面

    检查元素,已经没有sessionid了

    我们客户以看一下logout的源码

    def logout(request):
        """
        Remove the authenticated user's ID from the request and flush their session
        data.
        """
        # Dispatch the signal before the user is logged out so the receivers have a
        # chance to find out *who* logged out.
        user = getattr(request, 'user', None)
        if not getattr(user, 'is_authenticated', True):
            user = None
        user_logged_out.send(sender=user.__class__, request=request, user=user)
    
        # remember language choice saved to session
        language = request.session.get(LANGUAGE_SESSION_KEY)
        
        # 清空session
        request.session.flush()
    
        if language is not None:
            request.session[LANGUAGE_SESSION_KEY] = language
    
        if hasattr(request, 'user'):
            from django.contrib.auth.models import AnonymousUser
            # 把request.user置为AnonymousUser
            request.user = AnonymousUser()
    
    

    User对象

    User 对象属性:username, password(必填项)password用哈希算法保存到数据库

    is_authenticated方法

    如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。
    通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。 这个方法很重要, 在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name

    修改index视图函数,更改判断方式

    def index(request):
        # request.user是当前用户,如果没有登录则默认是AnonymousUser
        # print(request.user)
        # print(request.user.id)
        # print(request.user.username)
        # print(request.user.password)
    
        if request.user.is_authenticated:
            name = request.user.username
            return render(request, 'index.html', {'name': name})
        return redirect('/login/')
    
    

    注意
    is_authenticated是一个属性,没有括号,默认值为False

    @property
        def is_authenticated(self):
            return False
    

    清除缓存,再次访问index页面

    输入用户名和密码

    创建用户

    使用 create_user 辅助函数创建用户:

    修改urls.py,增加路径adduser

    from django.contrib import admin
    from django.urls import path
    from app1 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.login),
        path('index/', views.index),
        path('logout/', views.logout),
        path('adduser/', views.adduser),
    ]
    
    

    修改views.py,增加adduser视图函数
    def adduser(request):
        if request.method == 'POST':
            from django.contrib.auth.models import User
            username = request.POST.get('user')
            password = request.POST.get('pwd')
            User.objects.create_user(username=username, password=password)
            return HttpResponse('添加成功!')
        return render(request, 'adduser.html')
    
    

    访问adduser页面

    添加后查看auth_user表记录

    这里is_supeiuser为0,表示普通用户,如果你要创建超级用户,用create_superuser,注意创建超级用户要指定邮箱(对于Django2)


    ## 小结 ### 用户认证 认证成功返回user对象,失败返回None ```python user=auth.authenticate(username=user, password=pwd) ``` ### 登录 注册session ```python auth.login(request,user) # 全局变量 request.user=当前登陆对象(session中) ``` ### 注销 清除session,内部使用了request.session.flush() ```python auth.logout(request)
    ### 创建用户
    ```python
    from django.contrib.auth.models import User
    User.objects.create_user(username="robin",password=123)
    
    

    判断是否已认证

    request.user.is_authenticated
    
    

    补充:request.user是全局变量,在模板中也可以直接渲染 修改index.html ```html Title

    个人主页

    Hi! {{ request.user.username }}

    注销

    重新登录,效果是一样的
    ![](https://img2018.cnblogs.com/blog/1542801/201903/1542801-20190328221647554-1220700935.png)
  • 相关阅读:
    搭建Apache服务器并使用自签证书实现https访问
    常见加密算法
    awk命令用法
    systemd的新特性及常见的systemd unit类型分析
    kickstart文件制作与光盘镜像制作
    grub启动引导程序配置及命令行接口详解
    Linux启动流程(CentOS6)
    Linux相关网络命令
    rpm与yum,at与crontab,sed命令使用
    腾讯明眸极速高清升级2.0,助力韩国赛事超高清5G直播
  • 原文地址:https://www.cnblogs.com/zzliu/p/10617130.html
Copyright © 2020-2023  润新知