auth模块

之前我们在进行用户登录验证的时候,都是自己写代码,接收用户提交的数据,然后去数据库取数据进行匹配验证,其实Django已经给我们提供了内置的用户认证功能。不信的话你可以打开models.py,新建一个model类,然后执行python manage.py makemigrationss和python manage.py migrate,可以发现数据库中除了自己建的表之外,还有如下表:

  • auth_user
  • auth_group
  • auth_group_permissions
  • auth_permission
  • auth_user_groups
  • auth_user_user_permissions

    以上6张表都是用于认证的,其中auth_user表是用于用户认证的

    使用Django自带的认证功能,需要导入auth模块
from django.contrib import auth

auth里面封装了许多方法,用的最多的有三个

## authenticate方法
提供了用户认证,即验证用户名以及密码是否正确,一般需要username password两个关键字参数

如果认证信息有效,会返回一个 User 对象。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的!!

使用Pycharm新建项目authDemo, 执行2个命令,生成django需要的表

python manage.py makemigrations
python manage.py migrate

使用命令行创建一个超级用户

python manage.py createsuperuser

会提示输入用户名、邮箱、密码等,<font color='#ff0000'注意输入密码时是看不见的,光标也不会移动,输入完回车就行!

打开auth_user表,可以可以看到多了一条记录,其中密码是加密存储的

修改urls.py,增加路径

from django.contrib import admin
from django.urls import path
from app1 import views urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('index/', views.index),
]

修改views.py,增加视图函数
```python
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(type(ret))

print(ret.dict)

if ret:

return redirect('/index/')

return render(request, 'login.html')

def index(request):

return render(request, 'index.html')

<br>
在templates新建文件login.html和index.html
login.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form action="" method="post">
{% csrf_token %}
<label for="user">用户名</label>
<input type="text" name="user" id="user">
<label for="pwd">密码</label>
<input type="password" name="pwd" id="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>个人主页</h3> </body>
</html>

访问登录页面

登录成功跳转道index页面

查看控制台输出

liu
<class 'django.contrib.auth.models.User'>
{'_state': <django.db.models.base.ModelState object at 0x0000026910303518>, 'id': 2, 'password': 'pbkdf2_sha256$120000$1YA8aSwnUOkF$6B0WD0O/pplS1jw9MZCcehBm4U/qRu1ps3qEWIsD6oY=', 'last_login': None, 'is_superuser': True, 'username': 'liu', 'first_name': '', 'last_name': '', 'email': 'abc@qq.com', 'is_staff': True, 'is_active': True, 'date_joined': datetime.datetime(2019, 3, 28, 11, 39, 17, 253175, tzinfo=<UTC>), 'backend': 'django.contrib.auth.backends.ModelBackend'}

## login方法
login的语法为`login(HttpResponse, user)`,其接收一个HttpResponse对象,以及换一个认证的User对象,作用是使用django的session框架给某个已认证的用户加上sessionid等信息

修改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(type(user))
# print(user.__dict__)
if user:
# 登录,注册session,同时会把user封装道request中
auth.login(request, user)
return redirect('/index/')
return render(request, 'login.html') def index(request):
# request.user是当前用户,如果没有登录则默认是AnonymousUser
print(request.user)
print(request.user.id)
print(request.user.username)
print(request.user.password)
return render(request, 'index.html')

直接访问index

报错

控制台输出

AnonymousUser
None
(报错信息忽略)

request.user 默认是一个匿名对象,auth_user表的所有字段对应的值,都是空的

登录成功后,查看控制台输出

liu
2
liu
pbkdf2_sha256$120000$1YA8aSwnUOkF$6B0WD0O/pplS1jw9MZCcehBm4U/qRu1ps3qEWIsD6oY=

注意,request.user是全局变量,可以在任意代码中运用那么它是怎么实现的呢,答案是利用中间件实现的,我们来看一下settings里面的配置

红色方框里面的就是认证的中间件

auth.login(request, user)这句话执行之后,就注册session,产生了一个全局变量

上面的例子里没有登录就可以访问主页是不对的,应该加入判断


修改index视图函数
```python
def index(request):
# request.user是当前用户,如果没有登录则默认是AnonymousUser
# print(request.user)
# print(request.user.id)
# print(request.user.username)
# print(request.user.password)

user_id = request.user.id
print(user_id)
name = request.user.username
if user_id:
return render(request, 'index.html', {'name': name})
return redirect('/login/')
<br>
修改index.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <h3>个人主页</h3> <h3>Hi! {{ name }}</h3> </body>
</html>

logout方法

logput为注销,语法为auth.logout(request)

修改urls.py,增加路径logout

from django.contrib import admin
from django.urls import path
from app1 import views urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('index/', views.index),
path('logout/', views.logout),
]

修改views.py,增加logout视图函数

def logout(request):
auth.logout(request) # 清除cookie和session
return redirect('/login/')

该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

修改index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <h3>个人主页</h3> <h3>Hi! {{ name }}</h3> <a href="/logout/">注销</a> </body>
</html>

刷新页面

点击注销,跳转到了登录界面

检查元素,已经没有sessionid了

我们客户以看一下logout的源码

def logout(request):
"""
Remove the authenticated user's ID from the request and flush their session
data.
"""
# Dispatch the signal before the user is logged out so the receivers have a
# chance to find out *who* logged out.
user = getattr(request, 'user', None)
if not getattr(user, 'is_authenticated', True):
user = None
user_logged_out.send(sender=user.__class__, request=request, user=user) # remember language choice saved to session
language = request.session.get(LANGUAGE_SESSION_KEY) # 清空session
request.session.flush() if language is not None:
request.session[LANGUAGE_SESSION_KEY] = language if hasattr(request, 'user'):
from django.contrib.auth.models import AnonymousUser
# 把request.user置为AnonymousUser
request.user = AnonymousUser()

User对象

User 对象属性:username, password(必填项)password用哈希算法保存到数据库

is_authenticated方法

如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。

通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。 这个方法很重要, 在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name

修改index视图函数,更改判断方式

def index(request):
# request.user是当前用户,如果没有登录则默认是AnonymousUser
# print(request.user)
# print(request.user.id)
# print(request.user.username)
# print(request.user.password) if request.user.is_authenticated:
name = request.user.username
return render(request, 'index.html', {'name': name})
return redirect('/login/')

注意

is_authenticated是一个属性,没有括号,默认值为False

@property
def is_authenticated(self):
return False

清除缓存,再次访问index页面

输入用户名和密码

创建用户

使用 create_user 辅助函数创建用户:

修改urls.py,增加路径adduser

from django.contrib import admin
from django.urls import path
from app1 import views urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('index/', views.index),
path('logout/', views.logout),
path('adduser/', views.adduser),
]

修改views.py,增加adduser视图函数

def adduser(request):
if request.method == 'POST':
from django.contrib.auth.models import User
username = request.POST.get('user')
password = request.POST.get('pwd')
User.objects.create_user(username=username, password=password)
return HttpResponse('添加成功!')
return render(request, 'adduser.html')

访问adduser页面

添加后查看auth_user表记录

这里is_supeiuser为0,表示普通用户,如果你要创建超级用户,用create_superuser,注意创建超级用户要指定邮箱(对于Django2)

## 小结
### 用户认证
认证成功返回user对象,失败返回None
```python
user=auth.authenticate(username=user, password=pwd)
```
### 登录
注册session
```python
auth.login(request,user) # 全局变量 request.user=当前登陆对象(session中)
```
### 注销
清除session,内部使用了request.session.flush()
```python
auth.logout(request)

### 创建用户
```python
from django.contrib.auth.models import User
User.objects.create_user(username="robin",password=123)

判断是否已认证

request.user.is_authenticated

补充:request.user是全局变量,在模板中也可以直接渲染
修改index.html
```html

Title

个人主页

Hi! {{ request.user.username }}

注销

重新登录,效果是一样的
![](https://img2018.cnblogs.com/blog/1542801/201903/1542801-20190328221647554-1220700935.png)

Django之用户认证组件的更多相关文章

  1. python 全栈开发,Day79(Django的用户认证组件,分页器)

    一.Django的用户认证组件 用户认证 auth模块 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中: 如果用户存在于数据库中,然后再验证用户 ...

  2. django - 总结 - 用户认证组件

    用户认证组件 from django.contrib import auth 从auth_user表中获取对象,没有返回None,其中密码为密文,使用了加密算法 user = auth.authent ...

  3. django的用户认证组件

    DataSource:https://www.cnblogs.com/yuanchenqi/articles/9064397.html 代码总结: 用户认证组件: 功能:用session记录登录验证状 ...

  4. 06 django的用户认证组件

    1.用户认证组件 用户认证组件: 功能:用session记录登录验证状态 前提:用户表:django自带的auth_user 创建超级用户: python3 manage.py createsuper ...

  5. Django的用户认证组件,自定义分页

    一.用户认证组件 1.auth模块 from django.conrtrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: 1)authen ...

  6. 14 Django的用户认证组件

    用户认证 auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: 1.1 .authentica ...

  7. web框架开发-Django用户认证组件

    可以用认证组件做什么 针对session的缺陷, 跟新数据时,不跟新key键, 用户认证组件是删除后再重建 用户认证组件很多功能可以直接使用 利用用户认证表(auth_user,通过Django自己创 ...

  8. 10.Django用户认证组件

    用户认证组件: 功能:用session记录登录验证状态: 前提:用户表,django自带的auth_user 创建超级用户:python manage.py createsuperuser       ...

  9. Django用户认证组件

    用户认证 主要分两部分: 1.auth模块   from django.contrib import auth 2.User对象 from django.contrib.auth.models imp ...

随机推荐

  1. 深入浅出QOS详解(转)

    QOS学习笔记 (工作时间之余,总结了这些,累的食指快脱节了,现在还在恢复中,为的就是让文章质量再提高点,希望对大家有帮助!文章太长,为方便,我附件上文章原文.) QOS,服务质量.顾名思义,就是为了 ...

  2. 「SCOI2014」方伯伯运椰子 解题报告

    「SCOI2014」方伯伯运椰子 可以看出是分数规划 然后我们可以看出其实只需要改变1的流量就可以了,因为每次改变要保证流量守恒,必须流成一个环,在正负性确定的情况下,变几次是无所谓的. 然后按照套路 ...

  3. 牛客练习赛28 E迎风舞 (三分查找)

    链接:https://www.nowcoder.com/acm/contest/200/E来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...

  4. es6+的javascript拓展内容

    一.let,const 1.因为块级的作用域,这样打印01234,循环外打印i会报错 for (let i = 0; i < 5; i++) { setTimeout(console.log(i ...

  5. java 子类强转父类 父类强转子类

    Java 继承 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为. Java 子类强转父类 父类引用指向子类对象: jav ...

  6. codeforces Hello 2019(未写完)

    A. Gennady and a Card Game a题惯例签到题 题意:给你一张牌,再给你5张牌,判断能不能出一次牌... 所以只要检查第二行中的某个卡是否与第一行中的卡具有共同字符 有就输出YE ...

  7. poj2083 Fractal

    我一开始的想法是间断性的输出空格和solve(k-1) 但是发现问题很大. 雨菲:可以用一个数组保存啊 我:那不爆了? 雨菲:不会爆. 我一算:729 × 729,还真没爆. 然后就直接WA了.... ...

  8. bzoj1271 秦腾与教学评估

    SB题!!! 我TM困惑了一下午,三份代码答案全都不一样,后来才发现要用long long来二分... 拿记事本一改就A了. 我TM...... 这SB题目...... 这惨痛的事实充分说明了long ...

  9. 【CF1119E】Pavel and Triangles

    题目大意:有 N 种长度的边,第 i 种长度为 \(2^i\),给定一些数量的这些边,问最多可以组合出多少种三角形. 题解:应该是用贪心求解,不过选择什么样的贪心策略很关键. 首先分析可知,两个较大边 ...

  10. (九)逻辑运算,order by,desc

    逻辑运算 AND,OR,NOT ......where 表达式1  and 表达式2: ......where 表达式2  and 表达式1: SQL优化: SQL在解析where时是从右向左解析的. ...