10.Django用户认证组件
用户认证组件:
功能:用session记录登录验证状态;
前提:用户表,django自带的auth_user
创建超级用户:python manage.py createsuperuser kris的密码是abc123456
1.基于用户认证组件的登录验证信息储存
views.py
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.contrib import auth #from django.contrib.auth.models import User #自己找到那个接口做校验 auth_user那个表 def login(request): if request.method =="POST": user = request.POST.get("user") pwd = request.POST.get("pwd") #if 验证成功返回user对象,否则返回None user = auth.authenticate(username=user,password=pwd) if user: #用它封装好的做校验 auth.login(request,user) #auth.login这个方法需要传两个参数; request.user = user 就是当前登录对象;如果没有登录它拿到的是一个匿名对象 return redirect("/index/") return render(request, "login.html") def index(request): print("request.user:", request.user) #没有登录就会打印一个匿名对象 request.user: AnonymousUser
print("request.user:", request.user.username) #request.user: print("request.user:", request.user.id) #request.user: None print("request.user:", request.user.is_anonymous) #request.user: True #拿上边这几个值都可以判断用户是否登录。 if request.user.is_anonymous:
#if not request.user.user.is_authenticated: #它跟上边的是一样的 return redirect("/login/") #username = request.user.username #return render(request, "index.html",{"username":username}) 可以不这样写,当然这是一种传变量的方式。request.user是个全局变量,一直都是代表当前登录对象 return render(request, "index.html")
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post"> {% csrf_token %} 用户名<input type="text" name="user"> 密码<input type="text" name="pwd"> <input type="submit" value="submit"> </form> </body> </html>
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {#<h3> Hello {{ username }}</h3> 可以不给它传值了,request.user为全局#} <h3>Hello {{ request.user.username }}</h3> </body> </html>
创建用户kris 和 alex
C:\Users\Administrator\PycharmProjects\authDemo>python manage.py createsuperuser Username (leave blank to use 'administrator'): alex Email address: Password:alex1234 Password (again):alex1234 Superuser created successfully.
更新的时候它不像之前那样子,它把session_key 和session_data数据都更新了,之前都是只更新session_data,现在逻辑跟严谨了。
2.注册/注销用户功能
views.py
def logout(request): auth.logout(request) return redirect("/login/") def reg(request): if request.method=="POST": user = request.POST.get("user") pwd = request.POST.get("pwd") user = User.objects.create_user(username=user,password=pwd) #做注册,插入这张表中,一定要按照摘要算法插入,把password进行转换成密文 return redirect("/login/") return render(request,"reg.html")
reg.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>注册</h3> <form action="" method="post"> {% csrf_token %} 用户名<input type="text" name="user"> 密码<input type="text" name="pwd"> <input type="submit" value="submit"> </form> </body> </html>
index.html
<body>
<a href="/logout/">注销</a>
</body>
一点击注销按钮,就把django_session里边的记录都给清除了。
用户认证组件: 功能:用session记录登录验证状态; 前提:用户表,django自带的auth_user 创建超级用户:python manage.py createsuperuser kris的密码是abc123456 API from django.contrib import auth auth对象下面的方法 1 if 验证成功返回user对象,否则返回None user = auth.authenticate(username=user,password=pwd) 2 auth.login(request,user) #request.user:当前登录对象 3 auth.logout(request) from django.contrib.auth.models import User #User==auth_user user对象下面的方法 4 request.user.is_authenticated: 5 user=User.objects.create_user(username='',password='',email='') 补充: 匿名用户对象 匿名用户 class models.AnonymousUser django.contrib.auth.models.AnonymousUser 类实现了django.contrib.auth.models.User 接口,但具有下面几个不同点: id 永远为None。 username 永远为空字符串。 get_username() 永远返回空字符串。 is_staff 和 is_superuser 永远为False。 is_active 永远为 False。 groups 和 user_permissions 永远为空。 is_anonymous() 返回True 而不是False。 is_authenticated() 返回False 而不是True。 set_password()、check_password()、save() 和delete() 引发 NotImplementedError。 New in Django 1.8: 新增 AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User。 总结: if not:auth.login(request,user) request.user == AnonymousUser()#没有登录 else:request.user==登录对象 request.user是一个全局变量 在任何视图和模板中直接使用
3.基于用户认证组件的认证装饰器
如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。
通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。 这个方法很重要, 在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name
要求:
1 用户登陆后才能访问某些页面,
2 如果用户没有登录就访问该页面的话直接跳到登录页面
3 用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址
方法一
def order(request): if not request.user.is_outhenticated: return redirect("/login/") return render(request,"order.html")
方法二
django已经为我们设计好了一个用于此种情况的装饰器:login_requierd()
先在settings里边设置下我要跳转到哪个页面
STATIC_URL = '/static/' LOGIN_URL = "/login/" #跳转到哪里由我自己决定; 不加这个django会给你默认跳转到 127.0.0.1:8000/accounts/login/?next=/index/;设置好这个后跳转到:/login/?next=/index/(是访问index进行跳转的)
在views里边
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.contrib import auth from django.contrib.auth.models import User #自己找到那个接口做校验 from django.contrib.auth.decorators import login_required #引入 def login(request): if request.method =="POST": user = request.POST.get("user") pwd = request.POST.get("pwd") #if 验证成功返回user对象,否则返回None user = auth.authenticate(username=user,password=pwd) if user: auth.login(request,user) #request.user:当前登录对象 next_url = request.GET.get("next","/index/") #如果找不到就跳转到index页面 # return redirect("/index/") #不要写死了就跳转到index return redirect(next_url) #动态的根据参数来配 return render(request, "login.html") @login_required #有了装饰器,就不需要自己写下面的了 def index(request): # print("request.user:", request.user.username) # print("request.user:", request.user.id) # print("request.user:", request.user.is_anonymous) # # if request.user.is_anonymous: #把这些自己写的认证全关了,@login_required是django给我们封装好了的 # #if not request.user.is_authenticated: #这两个是一样的 # return redirect("/login/") # #username = request.user.username # #return render(request, "index.html",{"username":username}) return render(request, "index.html") def logout(request): auth.logout(request) return redirect("/login/") def reg(request): if request.method=="POST": user = request.POST.get("user") pwd = request.POST.get("pwd") user = User.objects.create_user(username=user,password=pwd) return redirect("/login/") return render(request,"reg.html") @login_required def order(request): # if not request.user.is_outhenticated: # return redirect("/login/") #可以加装饰器,不用自己这样写了 return render(request,"order.html")
若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递 当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。