zoukankan      html  css  js  c++  java
  • Django用户认证组件

    用户认证

    主要分两部分:

      1.auth模块  

        from django.contrib import auth

      2.User对象

        from django.contrib.auth.models import User

    用户认证组件key:

    1.大前提:针对的是django自带的auth_user表

    2.django下的auth_user 表创建用户

    3.request.user

      用户(user_obj)登录成功后:

        auth.login(request,user_obj)做了以下几件事:

          (1)过程赋值 request.user=user_obj

          (2)request.session["user_id"]=user_obj.pk ,将此项信息注入到session表中,session_data 加了一个键值对user_id=user_obj.pk

          做了3件事:

            1.创建一把session 钥匙 session_key = 随机字符串

             2.把这条记录放进seesion表中

            3.返回钥匙给浏览器

    4.每次请求request都是重新构建的,但AuthenticationMiddleware 这个中间件,在每次客户端发请求过来时做了一下几件事:

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]

    (1)读session_key 钥匙,在到session表中,找 session_id对应的值 ,找到对应的id后再去auth_user表中获取该用户对象,并做赋值操作:request.user=找到的用户对象

    (2)没有找到就用匿名用户对象  :  request.user=匿名用户对象

    auth模块

      from django.contrib import  auth

      from django.contrib.auth import authenticate, login ,logout

      1.authenticate()

        user_obj=authenticate(username=someone_username,password=someone_password)

        1.验证用户名或密码是否正确

        2.正确就返回用户对象,不正确则返回none

      2.login(request,user_obj)

        登录成功后:

          login(request,user_obj)  

          再重定向到指定页面

      3.logout

        def logout_view(request):

          logout(request)

          再重定向到登录页面

        logout(request) 大致做了以下几件事:

          1. request.session.flush()

          2.request.user=AnonymouseUser() #赋值给匿名用户对象

        

     User 对象

    User对象属性: username,password (必填),密码是加密的。

    1、user对象的 is_authenticated()

    1.request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name

    要求:

    1  用户登陆后才能访问某些页面

    2  如果用户没有登录就访问该页面的话直接跳到登录页面

    3  用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址

    #方法一  (非装饰器)
    
    def my_view(request):
      if not request.user.is_authenticated():
        return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
    
    #方式二(装饰器)
    from django.contrib.auth.decorators import login_required
          
    @login_required
    def my_view(request):

    @login_request装饰器的详解

    auth_user对象(request.user)的API:
    
        request.user.id 判断是否登录过
        request.user.is_authenticated() #判断是否登录过
        
        装饰器:@login_required  有从哪来回哪去功能
            django.contrib.auth.decorators import login_required
            如:
                1.没有登录就访问books页面,@login_required会给用户重定向到登录页面
    2.同时,跳转到登录页面默认地址 127.0.01:8000/account/login/?next=/books/ ; 因为global_settings 中默认:"/account/login/" from django.conf import global_settings LOGIN_URL="/account/login/" ,可以在项目的配置文件settings中修改该参数值: LOGIN_URL="/login/" @login_request装饰器实现从哪来到哪去的功能细节:
                地址栏数据部分:?next
    =/books/ 在后端可以通过 nex_path =request.GET.get("next") or "/books/"获取到,登录成功后直接重定向到该地址nex_path    nex_path =request.GET.get("next") or "/books/" 说明: 1.如果用户是直接选择login页面直接登录访问时,request.GET.get("next")的返回值就为None, 所以这时redirect(None),会报错,所以这种情况让它重定向到books页面就好。
    2.如果用户不是直接选择login页面,而是直接访问其他需要先登录后才能访问的页面,就回到登录页面,登录成功后,重从定向的页面路径获取: nex_path =request.GET.get("next")
    所以在登录视图函数中(非装饰器login视图函数,模拟装饰器@login_required实现登录成功后,跳转到之前的访问页面):
    def login(request): if request.method=="GET": return render(request,"login.html") else: user_obj=auth.authenticate(username=user,password=pwd) #查询是否有该对象,有就返回or返回none if user_obj: #登录成功 auth.login(request,user_obj) #print(request.path) #print(request.get_full_path())
                          #注意如果前端用的是ajax提交请求时,注意ajax中的url,需要时空,默认提交到本页面,不要指定login页面,否则获取不到
                          next_path 的路径
    next_path=request.GET.get("next") or "/books/" #next_path 表示之前的访问页面地址,如何是直接访问login页面则重定向到books页面
                          return redirect(next_path)
    else: return redirect("/login/")

    对@login_request 装饰器的使用需要注意点:

     到项目的settings配置文件中添加一个键值对:LOGIN_URL="/login/" ,  否则默认为:LOGIN_URL="/account/login/"

    2.创建用户

    auth_user表中创建用户:
    
        #auth_user 表: 
      from django.contrib.auth.models import User User.objects.create(username="egon",password="123") #这种方式创建的用户密码也是明文的 User.objects.create_user(username="alex",password="123")#密文 User.objects.create_superuser(username="taibai",password="123",email="122323223@qq.com")#密文,创建superuser时,需要email

    3.核对密码:check_password(passwd)

    用户需要修改密码的时候 首先要让他输入原来的密码 ,如果给定的字符串通过了密码检查,返回 True

    4.修改密码 :set_password() 

    user = User.objects.get(username='')
    user.set_password(password='')
    user.save 

    示例:

    1.注册:

    def sign_up(request):
     
        state = None
        if request.method == 'POST':
     
            password = request.POST.get('password', '')
            repeat_password = request.POST.get('repeat_password', '')
            email=request.POST.get('email', '')
            username = request.POST.get('username', '')
            if User.objects.filter(username=username):
                    state = 'user_exist'
            else:
                    new_user = User.objects.create_user(username=username, password=password,email=email)
                    new_user.save()
     
                    return redirect('/book/')
        content = {
            'state': state,
            'user': None,
        }
        return render(request, 'sign_up.html', content)  

    2.修改密码:

    @login_required
    def set_password(request):
        user = request.user
        state = None
        if request.method == 'POST':
            old_password = request.POST.get('old_password', '')
            new_password = request.POST.get('new_password', '')
            repeat_password = request.POST.get('repeat_password', '')
            if user.check_password(old_password):
                if not new_password:
                    state = 'empty'
                elif new_password != repeat_password:
                    state = 'repeat_error'
                else:
                    user.set_password(new_password)
                    user.save()
                    return redirect("/login/")
            else:
                state = 'password_error'
        content = {
            'user': user,
            'state': state,
        }
        return render(request, 'set_password.html', content)
  • 相关阅读:
    Nginx会话保持之nginx-sticky-module模块
    企业级分布式应用服务EDAS _Dubbo商业版_微服务PaaS平台 【EDAS Serverless 运维 创业】
    git repository description
    运维成长
    jenkins+maven+tomcat集群发布
    Leaf——美团点评分布式ID生成系统 UUID & 类snowflake
    tomcat redis 集群 session共享
    JEECG & JEESite Tomcat集群 Session共享
    分布式Tomcat session会话Sticky Sessions问题
    Memcached 集群架构与memcached-session-manager
  • 原文地址:https://www.cnblogs.com/knighterrant/p/10260554.html
Copyright © 2011-2022 走看看