一、Django的用户认证组件
用户认证
auth模块
在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中;
如果用户存在于数据库中,然后再验证用户输入的密码,这样一来就要自己编写大量的代码。
事实上,Django已经提供了内置的用户认证功能。
在使用"python manage.py makemigrationss"和"python manage.py migrate"迁移完成数据库之后
根据配置文件settings.py中的数据库段生成的数据表中已经包含了6张进行认证的数据表,分别是
- auth_user
- auth_group
- auth_group_permissions
- auth_permission
- auth_user_groups
- auth_user_user_permissions
进行用户认证的数据表为auth_user
要使用Django自带的认证功能,首先要导入auth模块
from django.contrib import auth #导入auth模块
django.contrib.auth中提供了许多方法,这里主要介绍其中的三个:
1.1 、authenticate()
提供了用户认证,即验证用户名以及密码是否正确,一般需要username password两个关键字参数
如果认证信息有效,会返回一个 User 对象。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的!!
user = authenticate(username='someone',password='somepassword')
举例:
使用Pycharm新建项目authDemo
执行2个命令,生成django需要的表
python manage.py makemigrations
python manage.py migrate
我们只需要用到auth_user表,就可以了!
打开auth_user表,默认是空的。其中2个字段,username和password是必须要有的!
注意:添加用户,不能直接插入记录,必须使用命令行
创建超级用户
python manage.py createsuperuser
效果如下:
查看auth_user表,发现多了一条记录
注意:密码是加密的,不能直接查表验证。必须使用authenticate() 进行验证!
修改urls.py,增加路径
from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), ]
修改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 ret = auth.authenticate(username=user,password=pwd) print(ret) print(ret.__dict__) if ret: return redirect("/index/") return render(request,"login.html") def index(request): return render(request, "index.html")
在templates新建文件login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post"> {% csrf_token %} <lable>用户名</lable><input type="text" name="user"> <lable>密码</lable><input type="password" name="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>HI.</h3> </body> </html>
访问登录页面
跳转首页
查看Pycharm控制台输出
xiao {'email': '', 'last_login': None, 'is_superuser': True, 'is_staff': True, 'date_joined': datetime.datetime(2018, 7, 9, 11, 2, 16, 775761, tzinfo=<UTC>), 'last_name': '', '_state': <django.db.models.base.ModelState object at 0x000002E6F03447B8>, 'username': 'xiao', 'password': 'pbkdf2_sha256$100000$LAp6T0YPt6Xj$37j4PuLHs3W/HRjQQyn4KYZZQog9QWrbmatAB+PC6pM=', 'id': 1, 'backend': 'django.contrib.auth.backends.ModelBackend', 'is_active': True, 'first_name': ''}
1.2 、login(HttpRequest, user)
该函数接受一个HttpRequest对象,以及一个认证了的User对象
此函数使用django的session框架给某个已认证的用户附加上session id等信息。
修改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(user.__dict__) if user: #登录,注册session # 全局变量 request.user=当前登陆对象(session中) auth.login(request,user) return redirect("/index/") return render(request,"login.html") def index(request): print(request.user) # 默认是一个匿名对象 print(request.user.id) print(request.user.username) return render(request, "index.html")
直接访问index
查看Pycharm控制台输出:
AnonymousUser
None
request.user 默认是一个匿名对象,auth_user表的所有字段对应的值,都是空的。
当登录成功之后,该对象才会有值。
访问登录页面 http://127.0.0.1:8000/login/
重新登录一次
查看Pycharm控制台输出:
xiao
1
xiao
request.user是全局变量,可以在任意代码中运用
它用了一个中间件,在settings.py中的MIDDLEWARE配置项里
'django.contrib.auth.middleware.AuthenticationMiddleware',
这句只要执行,那么就能注册session,产生一个全局变量
auth.login(request,user)
在上面的例子中,直接访问首页都可以,连登录的省掉了,这是不对的。
加入判断session
修改index视图函数
def index(request): print(request.user) # 默认是一个匿名对象 print(request.user.id) print(request.user.username) if not request.user.id: return redirect("/login/") name = request.user.username return render(request, "index.html",{"name":name})
修改index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>HI. {{ name }}</h3> </body> </html>
直接输入url: http://127.0.0.1:8000/index/
未完待续...