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)
原文地址:https://www.cnblogs.com/knighterrant/p/10260554.html