Django之驗證碼

驗證碼

咱們在登錄網站的時候就會遇到驗證碼下面會寫一個關於驗證碼的示列css

先建立一個Django項目,作好準備工做html

須要的環境爲:jquery

Djangoajax

login_img.htmldjango

kumo.ttf字體(能夠在百度上下載)bootstrap

bootstrap.min.csssession

還有一些依賴關係,有一些模塊使用pip安裝就好app

viws.py的試圖dom

from django.shortcuts import render, HttpResponse, redirect
from django.contrib import auth
from django.http import JsonResponse
from PIL import Image, ImageDraw, ImageFont
import random


# Create your views here.
# 生成隨機的驗證碼圖片,這個能夠單獨作一個模塊模塊裏面
def get_valid_img(request):
    # 隨機獲取一個顏色代碼(225, 255, 255)這種形式
    def get_random_color():
        return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)

    # 建立一個畫板對象
    img_obj = Image.new('RGB', (220, 35), (255, 255, 255))  # 背景色爲白色
    # img_obj = Image.new('RGB', (220, 35), get_random_color())  # 背景色隨機
    # 建立一個畫筆對象在畫板對象上寫字符
    draw_obj = ImageDraw.Draw(img_obj)
    # 加載一個字體獲得字體對象, 設置字體大小
    font_obj = ImageFont.truetype("static/font/kumo.ttf", 28)
    # 開始生成隨機字符串而且寫到圖片上
    tmp_list = []
    for i in range(5):
        u = chr(random.randint(65, 90))  # 生成大寫字母, 根據大寫字母在ascii中的位置轉換
        l = chr(random.randint(97, 122))  # 生成小寫字母,根據小寫字母在ascii中的位置轉換
        n = str(random.randint(0, 9))  # 生成數字,注意要轉換成字符串類型
        tmp = random.choice([u, l, n])
        tmp_list.append(tmp)
        draw_obj.text((20 + 40 * i, 0), tmp, fill=get_random_color(), font=font_obj)
    # print(''.join(tmp_list))
    # print('生成的驗證碼'.center(80, '='))
    request.session["valid_code"] = ''.join(tmp_list)
    # 加干擾線
    width = 220  # 圖片寬度(防止越界)
    height = 35
    for i in range(4):
        x1 = random.randint(0, width)
        x2 = random.randint(0, width)
        y1 = random.randint(0, height)
        y2 = random.randint(0, height)
        draw_obj.line((x1, y1, x2, y2), fill=get_random_color())

    # 加干擾點
    for i in range(40):
        draw_obj.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw_obj.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())

    # 將生成的圖片保存在磁盤上
    # with open("s10.png", "wb") as f:
    #     img_obj.save(f, "png")
    # 把剛纔生成的圖片返回給頁面
    # with open("s10.png", "rb") as f:
    #     data = f.read()
    # 不須要在硬盤上保存文件,直接在內存中加載就能夠
    from io import BytesIO
    io_obj = BytesIO()
    # 將生成的圖片數據保存在io對象中
    img_obj.save(io_obj, "png")
    # 從io對象裏面取上一步保存的數據
    data = io_obj.getvalue()
    return HttpResponse(data)


def login_img(request):
    ret = {'status': 0, 'msg': ''}
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        valid_code = request.POST.get('valid_code')
        if valid_code and valid_code.upper() == request.session.get("valid_code", "").upper():
            user = auth.authenticate(username=username, password=password)
            if user:
                auth.login(request, user)
                ret['msg'] = '/index/'
            else:
                ret['status'] = 1
                ret['msg'] = '用戶名或密碼錯誤'
        else:
            ret['status'] = 1
            ret['msg'] = '驗證碼錯誤'
        return JsonResponse(ret)
    return render(request, 'login_img.html')

 

login_img.htmlpost

{#使用圖形驗證碼#}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>歡迎登錄</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/mystyle.css">
</head>
<body>
<div class="container">
    <div class="row">
        <form class="form-horizontal col-md-6 col-md-offset-3 login-form">
            {% csrf_token %}
            <div class="form-group">
                <label for="login-username" class="col-sm-2 control-label">用戶名</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="login-username" name="username" placeholder="用戶名">
                </div>
            </div>
            <div class="form-group">
                <label for="login-Password" class="col-sm-2 control-label">密碼</label>
                <div class="col-sm-10">
                    <input type="password" class="form-control" id="login-Password" name="password" placeholder="密碼">
                </div>
            </div>
            <div class="form-group">
                <label for="login-valid_code" class="col-sm-2 control-label">驗證碼</label>
                <div class="col-sm-10">
                    <input type="text" name="valid_code" id="login-valid_code">
                    <img id="valid-img" class="valid-img" src="/get_valid_img.png?" alt="">
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="button" class="btn btn-default" id="login-button">登錄</button>
                    <span class="login-error"></span>
                </div>
            </div>
        </form>
    </div>
</div>
<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script>
    $("#login-button").on("click", function () {
        // 獲取用戶名、密碼和驗證碼
        var username = $("#login-username").val();
        var password = $("#login-Password").val();
        var valid_code = $("#login-valid_code").val();
        // Ajax發送請求
        $.ajax({
            url: '/login/',
            type: 'post',
            data: {
                'username': username,
                'password': password,
                'valid_code': valid_code,
                'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()
            },
            success: function (data) {
                if (data.status) {
                    //登錄失敗
                    $(".login-error").text(data.msg);


                } else {
                    // 登錄成功
                    location.href = data.msg;
                }

            }

        })
    });
    // 當input框獲取焦點時將以前的錯誤清空而且清空input裏面的值
    $("#login-username,#login-Password,#login-valid_code").focus(function () {
        // 將以前的錯誤清空
        $(this).val('');
        $(".login-error").text("");
    });

    // 點擊驗證碼圖片 刷新驗證碼
    $("#valid-img").click(function () {
        $(this)[0].src += "?";
    })
</script>
</body>
</html>

上面用到的mystyle.css樣式爲

.login-form {
    margin-top: 70px;
}
.valid-img {
    height: 35px;
    width: 220px;
}

.login-error {
    color: red;
}

urls.py

from django.conf.urls import url
from django.contrib import admin
from blog import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login_img/$', views.login_img, name='login_img'),
    url(r'^get_valid_img.png/', views.get_valid_img),
    url(r'^index/', views.index),
]

 上面就是一個關於使用圖片驗證碼的一個例子,咱們其實能夠把生成圖片的功能封裝起來。

上面咱們在登錄驗證密碼的事有用到的是Django的自帶的認證系統。

咱們還能夠使用網上提供的極速驗證碼,這個能夠直接在百度上搜,他提供了幾種驗證方式。也有使用文檔。

有興趣的能夠本身看看。

相關文章
相關標籤/搜索