内容纲要

1.序言

当用户进行登录操作时,确保用户身份的安全性至关重要。我们常常需要判断登录请求是否是人为发出,在登录操作中使用验证码,可以有效地防止机器人或恶意攻击者,通过恶意方式尝试登录系统或进行不法操作。

Django是一个功能强大的Web框架,实在为开发者考虑的太过于周到了,简直是管家式服务,连验证码模块都帮开发者做好了,以便于开发人员使用方便和简单的方式,来确保用户身份的安全。Django中提供的验证码模块可以非常轻松地集成到应用程序中,从而实现登录操作的安全性。

除了验证码模块之外,Django还提供了很多其他的安全性功能,如使用HTTPS、限制登录尝试次数等。这些安全性功能可以有效地保护用户登录的安全,并防止恶意攻击。

在开发应用程序时,我们应当充分考虑这些安全性功能,并尽可能地使用它们,以确保用户数据的安全和隐私。
django

2.验证码配置

首先,我们需要安装和配置django-simple-captcha模块。你可以通过运行以下命令来安装该模块:

pip install django-simple-captcha

接下来,我们需要在Django的设置文件中添加以下配置:

# settings.py

INSTALLED_APPS = [
    ...
    'captcha',
]

CAPTCHA_LENGTH = 6  # 验证码长度
CAPTCHA_FONT_SIZE = 30  # 验证码字体大小

本文中为了操作简单,我们只做一些简单的配置。captcha模块还可以配置验证码的不同方式,如配置CAPTCHA_CHALLENGE_FUNCT:

CAPTCHA_CHALLENGE_FUNCT= 'captcha.helpers.random_char_challenge' #验证码为随机字符串
CAPTCHA_CHALLENGE_FUNCT= 'captcha.helpers.math_challenge' # 验证码为简单数学计算
CAPTCHA_CHALLENGE_FUNCT= 'captcha.helpers.word_challenge' # 验证码为单词

同样也可以设置超时时间CAPTCHA_TIMEOUT,这里就不再赘述,如有更多需要,可查阅相关资料,或自定义验证方式。

3.登录逻辑验证

然后,我们新建一个登录表单 LoginForm , 在你的登录表单中,你可以添加一个验证码字段,并将其与django-simple-captcha模块中的 CaptchaField字段关联起来。你的表单可能如下所示:

from django import forms
from captcha.fields import CaptchaField

class LoginForm(forms.Form):
    username = forms.CharField()
    password = forms.CharField(widget=forms.PasswordInput)
    captcha = CaptchaField()

接下来,我们在前文:Django教程:视图介绍及使用提到的视图函数中,处理登录逻辑和验证码的验证。以下是一个简单的示例:

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
from .forms import LoginForm

def login_view(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            # 验证用户名密码是否正确
            user = authenticate(username=username, password = password)
            if user:
                login(request, user)
                # 登录成功,跳转到首页
                return redirect('/auth/index')
            else:
                form.add_error(field='username',error='用户名或密码错误!')
        else:
            form.add_error(field='captcha', error='验证码错误')
        return render(request, 'login.html', {'form': form})
    login_form = LoginForm()
    return render(request, 'login.html', {'form': login_form})

在上面的例子中,form.is_valid()会判断验证码是否正确。如果验证码正确,我们继续验证用户名和密码。如果用户名和密码也是正确的,我们就调用login函数来标记用户为已登录状态,然后将用户重定向到 /auth/index 页面。

django

4.渲染验证码

哇,前面的步骤介绍完了,后台的校验逻辑也写完了,那么,我们怎么让用户看到和输入正确的验证码呢?首先,如果验证码是个图片,它总得有个URL地址吧?所以,我们需要在urls.py中,把验证码的路由,添加到 urlpatterns中。

urlpatterns = [
    path('admin/', admin.site.urls),
    path('auth/', include('oauth.urls')), # 新建一个oauth app,用于实现登录
    path('captcha', include('captcha.urls')) # django 验证码登录路由
]

path('auth/', include('oauth.urls')) 是我在oauth app 中新建了一个urls.py文件,其内容如下:

from django.urls import re_path as url
from .views import login_view, index_view, logout_view

urlpatterns = [
    url(r'login', login_view),
    url(r'logout', logout_view),
    url(r'index', index_view)
]

这就是路由分离,为方便表达,我们统一将项目同名文件下的urls.py文件称为主路由,项目app内的urls.py称为子路由。并通过app的子路由,单独管理,实现app间路由隔离,同时使我们的项目urls.py看起来不那么乱糟糟的。

其次,我们就需要开始编写登录页面——login.html了。最后,需要在登录模板中呈现验证码字段。你可以使用form.captcha来渲染验证码字段,并使用form.captcha.errors来显示相关的错误信息。

<!-- login.html -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录</title>
</head>

<body>
    <div>
        <form method="POST">
            {% csrf_token %}
            <div>
                <label for="username">账户</label>{{ form.username }}
            </div>
            <div></div><label for="password">密码</label>{{ form.password }}
    </div>
    <div><label for="captcha">验证码</label>{{ form.captcha.label_tag }} </div>
    <div>{{ form.captcha }}</div>

    {% if form.captcha.errors %}
    <span>{{ form.captcha.errors }}</span>
    {% endif %}

    <button type="submit">登录</button>
    </form>
    </div>
</body>

</html>

5.登录验证

输入登录地址:http://localhost:8000/auth/login
django-captcha

故意输错验证码,会提示我们验证码错误,并重新刷新新的验证码。

django-captcha

输入我们之前文章Django教程:ORM模型介绍及使用中,通过python manage.py createsuperuser 命令创建的admin账户和密码。

Bingo! 登录成功!

loginsuccess

6.注销登录

注销登录比较简单,直接调用django为我们提供的logout方法即可。

# 用户登出
def logout_view(request):
    logout(request)
    return redirect('/auth/login')

记得配置路由哦。

7. login_required装饰器

login_required装饰器的主要用途是限制未登录用户的访问, 最原始的办法就是我们可以使用is_authenticated来判断用户是否是登录状态。

from django.conf import settings
from django.shortcuts import redirect

def my_view(request):
    if not request.user.is_authenticated:
        return redirect(f"{settings.LOGIN_URL}?next={request.path}")

Django提供了login_required(redirect_field_name='next', login_url=None)装饰器,如本文的index视图:

from django.contrib.auth.decorators import login_required

# 未登录,重定向至登录页
@login_required(login_url='/auth/login')
def index_view(request):
    return render(request, 'index.html')

redirect_field_name标识的是跳转URL参数的名称,Django中默认是next,通常这个参数传递的是当前访问的路由,而login_url则是指定登录链接,如果装饰器中不指定,则默认是 settings.LOGIN_URL参数。

8.结语

本文主要介绍了当在Django中使用验证码来增加登录安全性时,可以按照以下步骤操作:

  • 1、安装django-simple-captcha验证码模块
  • 2、配置验证码模块,包括设置验证码的长度、样式、过期时间等
  • 3、修改登录视图,添加验证码的验证逻辑。
  • 4、前端显示:在登录页面的HTML模板中,添加验证码的输入框和相关的HTML元素
  • 5、登出处理

在本文基础上,我们也可以增加一些登录限制。例如,可以限制登录尝试次数,达到一定次数后需要等待一段时间才能继续尝试。这可以有效地防止恶意攻击者使用暴力破解方法。

需要注意的是,验证码只是增加登录安全性的一种方式,也可以结合其他方法一起使用,如使用强密码策略、双因素认证等。根据项目的需求和风险评估,选择合适的安全措施并进行综合应用。

以上就是Django中使用验证码实现用户登录登出的基本步骤。你可以根据你的项目需求和具体情况进行修改和扩展。希望这些示例能对你有所帮助!

By liu luli

8年IT行业从业经验,参与、负责过诸多大型项目建设。掌握多门编程语言,对Java、Python编程有较为深刻的理解。现为杭州某公司开发负责人。

One thought on “Django基础教程:实现验证码登录登出”

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注