Django用户登录的实现及随机验证码功能

Django用户登录的实现及随机验证码功能

使用自带的登录视图

登录URL

from django.contrib.auth.views import login, logout

urlpatterns = [
    url(r'^login/$', login, name='login'),
    url(r'^logout/$', logout, name='logout'),
]

settings中创建登录链接

LOGIN_REDIRECT_URL = reverse_lazy('event:list')
LOGIN_URL = reverse_lazy('login')
LOGOUT_URL = reverse_lazy('logout')

自定义登录模板

在应用的templates目录下,创建registration文件夹,然后创建login.html文件,将优先使用这个模板进行登录

自定义登录视图进行验证登录

Django用户登录的实现及随机验证码功能_第1张图片
image.png
Django用户登录的实现及随机验证码功能_第2张图片
image.png

创建登录视图my_login(request)

from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User


# 自定义登录视图
def my_login(request):
    if request.method == 'POST':
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        verify = request.POST.get('verify', '')
        verify_session = request.session.get('verify', '')
        next_url = request.GET.get('next')
        # print('session中的验证码', verify_session)
        # print('输入的验证码:', verify)
        if verify.lower() == verify_session.lower():
            if User.objects.filter(username=username):
                login_user = authenticate(username=username, password=password)
                if login_user:
                    login(request, login_user)
                    if next_url and next_url.strip() != '':
                        # 如果下一跳地址不空,且不为空字符串,则登录成功跳回登录前的页面
                        return redirect(next_url)
                    else:
                        # 登录成功,跳转到主页
                        return redirect(reverse('index'))
                else:
                    msg_password = '密码错误,请检查'
            else:
                msg_username = '账户不存在,请重新注册'
        else:
            msg_verify = '验证码错误,请重新输入'

    next_url = request.GET.get('next', '')  # 访问登录,首先获取next的值,如果没有,则next_url赋值为''
    return render(request, 'registration/login.html', locals())

验证码视图verify_image(request, width, height)

# 返回验证码图片
def verify_image(request, width, height):
    words_count = 4  # 验证码中的字符长度
    width = int(width)  # 图片宽度
    height = int(height)  # 图片高度
    size = int(min(width / words_count, height) / 1.3)  # 字体大小设置
    bg_color = (randint(200, 255), randint(200, 255), randint(200, 255))   # 随机背景色(浅色)
    img = Image.new('RGB', (width, height), bg_color)  # 创建图像
    # 第一个参数是颜色通道,这里使用了RGB通道,还有其他的一些通道,如CMYK之类的,但不用管
    # 第二个参数是由宽高组成的元组,数字
    # 第三个参数是图片的背景色,这里用rgb的颜色显示,例如( 255, 255, 255),注意这是元组

    font = ImageFont.truetype('arial.ttf', size)  # 导入字体
    # 用到了ImageFont的truetype函数,可以自动查询电脑中的字体
    # 第一个参数是字体名字
    # 第二个参数是字体大小
    # 注意这个是windows系统下默认的字体,其他系统自己找

    draw = ImageDraw.Draw(img)  # # 创建画笔
    # 用到了ImageDraw的Draw函数
    # 有且只有一个参数,就是之前创建的画布

    # text = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    text = string.digits + string.ascii_letters  # 数字+大写字母
    verify_text = ''
    for i in range(words_count):
        text_color = (randint(0, 160), randint(0, 160), randint(0, 160))  # 确定文字的颜色,要随机的颜色,颜色要比较深
        left = width * i / words_count + (width / 4 - size) / 2  # i为第几个文字
        top = (height - size) / 2

        word = text[randint(0, len(text) - 1)]
        verify_text += word
        draw.text((left, top), word, font=font, fill=text_color)
        # 写字需要使用draw的text方法
        # 第一个参数是一个坐标轴元组,分别是距离左边和上边的距离
        # 第二个参数是要写的字(字符串)
        # 后面的两个参数分别是字体和字体颜色

    for i in range(30):
        text_color = (255, 255, 255)  # 颜色:白色
        left = randint(0, width)  # 位置:随机
        top = randint(0, height)
        draw.text((left, top), '*', font=font, fill=text_color)

    for i in range(5):
        line_color = (randint(0, 160), randint(0, 160), randint(0, 160))  # 颜色:随机
        line = (randint(0, width), randint(0, height), randint(0, width), randint(0, height))  # 位置:头尾都随机
        draw.line(line, fill=line_color)
        # 画线条需要使用draw的line方法
        # 第一个参数是包含了两个坐标的元组,分别是线条一头一尾的坐标
        # 后面的参数是线条的颜色

    del draw

    # StringIO,可以将图片缓存到内存里面,读取后就清空内存
    image_stream = BytesIO()  # 建立一个缓存对象
    # print(image_stream)  # 类似于:<_io.BytesIO object at 0x0000022CE22C00F8>
    img.save(image_stream, 'jpeg')  # 将图片保存到内存中
    # print(img, image_stream.getvalue())
    request.session['verify'] = verify_text  # 保存相应的文字在session里面
    return HttpResponse(image_stream.getvalue(), 'image/jpeg')  # 返回内存中的图片

修改登录URL

from .views import my_login


urlpatterns = [
    # url(r'^login/$', login, name='login'),
    url(r'^login/$', my_login, name='login'),
    url(r'^logout/$', logout, name='logout'),
    url(r'^verify_image/(\d+)/(\d+)/$', verify_image, name='verify_image')  # http://127.0.0.1:8000/account/verify_image/200/80/
]

自定义登录模板

{% extends "base_account.html" %}

{% block title %}登录{% endblock %}

{% block content %}
{% endblock %}

你可能感兴趣的:(Django用户登录的实现及随机验证码功能)