用户认证
在进行登陆案例的时候,效验用户名和密码一般是通过用模型类调用objects方法获得的数据库中的用户名和密码与浏览器发来的用户名和密码进行对应效验
在Django中效验用户名和密码可以通过authenticate()
使用 authenticate() 来验证用户。它使用 username 和 password 作为参数来验证,对每个身份验证后端(authentication backend )进行检查。如果后端验证有效,则返回一个:class:`~django.contrib.auth.models.User 对象。如果后端引发 PermissionDenied错误,将返回 None。
模板代码:
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
# A backend authenticated the credentials
else:
# No backend authenticated the credentials
·
记住用户的登陆状态
果有一个已验证的用户想附加到当前会话(session)中,可以通过 login()
函数完成。
login(request, user, backend=None)
要在视图中让用户登录,使用 login() 。它需要 HttpRequest 对象和 User 对象。通过 Django 的 session 框架, login() 会在 session 中保存用户的ID。
注意,在匿名会话期间设置的任何数据都会在用户登录后保留在会话中。
使用authenticate()
和login()
,代码实例:
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
# 用户效验成功
# 记住用户登陆状态
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...
·
配置redis作为Django默认缓存,缓存session信息
在Django中默认session信息保存在数据库中的django_session表中,那么每一次去取得session值的时候都需要到数据库中进行一次读写,效率很低而且消耗很大
则可以使用 redis 进行缓存session信息
1)安装django-redis
pip install django-redis
2)在Django的settings.py文件中配置django的默认缓存配置
# 配置Django缓存存储
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://192.168.43.85/2",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
3)配置session存储引擎
# 让Django默认使用缓存作为存储session储存后端,这样也不需要安装任何额外的 backend
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
4)打开对应主机的redis服务,即可进行session缓存
·
·
登出用户,删除用户的登录状态
logout(request)
如果已经通过 django.contrib.auth.login()
登录的用户想退出登录,可以在视图中使用 django.contrib.auth.logout()
。
from django.contrib.auth import logout
def logout_view(request):
logout(request)
注意,如果用户未登录,logout() 不会报错。
调用 logout() 后,当前请求的会话数据会被全部清除(即清除session)。这是为了防止其他使用同一个浏览器的用户访问前一名用户的会话数据。
·
·
记录用户的注册或者活跃状态is_active
Django2.0 版本以后用authenticate进行用户效验,即便用户名和密码输入正确但是is_active
属性为0的话依然返回None
如Daniel所说,如果你使用的是默认的后端数据库模型( ModelBackend ),那么你就不需要在登录的视图函数中去检查你的 is_active
属性
如果你想在不检查is_active
属性的前提下,只要用户名和密码正确就可以通过authenticate返回一个用户对象,则只需要在setting.py文件中加上:
# 配置允许使用所有的后端模型,即不需要判断is_active属性就可以通过authenticate返回一个用户对象
AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.AllowAllUsersModelBackend']
这样就可以做以下的判断
# 业务处理: 登陆效验
user = authenticate(request, username=username, password=pwd)
if user is not None:
if user.is_active:
# 用户已激活
# 记录用户的登陆状态
login(request, user)
# 跳转到首页
return redirect(reverse('goods:index'))
else:
# 用户未激活
return render(request, 'login.html', {'errmsg': '账户未激活'})
else:
# 用户名或密码错误
return render(request, 'login.html', {'errmsg': '用户名密码错误'})
·
判断用户是否是登录状态
在Django中封装了判断用户是否是登录状态的方法:
login_required()
装饰器
使用方法:
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
@login_required(login_url='自定义的url')
def my_view2(requst):
...
@login_required(redirect_field_name='自定义的模板文件名'):
def my_view3(request):
...
参数
login_url
和redirect_field_name
都是当用户未登录时要重定向的url或者html页面
login_required()
会执行以下操作:
● 如果用户没有登录,会重定向到 settings.LOGIN_URL
(可在settings.py文件中重写LOGIN_URL的url值,则会重定向到指定的url页面中) ,并传递绝对路径到查询字符串中。例如: /accounts/login/?next=/polls/3/ 。
● 如果用户已经登录,则正常执行视图。视图里的代码可以假设用户已经登录了。
·
** 当在视图文件中该视图使用的是类视图,没有函数可以加装饰器时,可以在配置路由时增添配置
例如:
from django.contrib.auth.decorators import login_required
from django.urls import path
from apps.user.views import *
urlpatterns = [
path('', login_required(UserInfoView.as_view()), name='userinfo')
]
·
上述方法在Django中也有已经封装好的方法👇
·
LoginRequiredMixin
使用基于类的视图时,可以使用 LoginRequiredMixin
实现和 login_required 相同的行为。这个 Mixin 应该在继承列表中最左侧的位置。
示例代码:
from django.contrib.auth.mixins import LoginRequiredMixin
class Myview(LoginRequiredMixin, View):
login_url = '指定重定向的url路径'
redirect_field_name = '指定重定向的模板文件'
·
·
判断用户是否已经登陆
浏览器在向服务器的每次请求都会提供 request.user
属性。如果当前没有用户登录,这个属性将会被设置为 AnonymousUser 实例对象,否则将会被设置为 User 实例对象。
request.user.is_authenticated
当request.user返回的是AnonymousUser实例对象时,request.user.is_authenticated
返回 False
当request.user返回的是User实例对象时,request.user.is_authenticated
返回 True
同时request.user也会自动传入模板文件中。在模板文件中可以直接使用
代码实例:
<div class="fr">
{% if user.is_authenticated %}
<div class="login_btn fl">
欢迎您:<em>{{ user.username }}</em>
<span>|</span>
<a href="{% url 'user:logout' %}">退出</a>
</div>
{% else %}
<div class="login_btn fl">
<a href="{% url 'user:login' %}">登录</a>
<span>|</span>
<a href="{% url 'user:register' %}">注册</a>
</div>
{% endif %}