用户认证
主要分两部分:
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)