python+Django自己生成驗證碼


  1.views.py

from django.shortcuts import render, HttpResponse

from django.http import JsonResponse

from django.contrib import auth
from PIL import Image, ImageDraw, ImageFont
import random
from io import BytesIO


# Create your views here.


# 自己生成驗證碼的登錄

def login(request):
    if request.method == "POST":
        # 初始化一個給AJAX返回的數據
        ret = {"status": 0, "msg": ""}
        # 從提交過來的數據中 取到用戶名和密碼
        username = request.POST.get("username")
        pwd = request.POST.get("password")
        valid_code = request.POST.get("valid_code")  # 獲取用戶填寫的驗證碼
        if valid_code and valid_code.upper() == request.session.get("valid_code", "").upper():
            # 驗證碼正確
            # 利用auth模塊做用戶名和密碼的校驗
            user = auth.authenticate(username=username, password=pwd)
            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.html")


# 獲取驗證碼圖片的視圖
def get_valid_img(request):
    # 獲取隨機顏色的函數
    def get_random_color():
        return random.randint(0, 255), random.randint(0, 255), random.randint(0, 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))  # 生成大寫字母
        l = chr(random.randint(97, 122))  # 生成小寫字母
        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)

    # 保存到session
    request.session["valid_code"] = "".join(tmp_list)
    # 加干擾線
    width = 220  # 圖片寬度(防止越界)
    height = 35
    for i in range(5):
        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())

    # 不需要在硬盤上保存文件,直接在內存中加載就可以
    io_obj = BytesIO()
    # 將生成的圖片數據保存在io對象中
    img_obj.save(io_obj, "png")
    # 從io對象里面取上一步保存的數據
    data = io_obj.getvalue()
    return HttpResponse(data)
View Code

 2.urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^get_valid_img.png/', views.get_valid_img),
]
View Code

3.login.html
<!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="username" class="col-sm-2 control-label">用戶名</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="username" name="username" placeholder="用戶名">
                </div>
            </div>
            <div class="form-group">
                <label for="password" class="col-sm-2 control-label">密碼</label>
                <div class="col-sm-10">
                    <input type="password" class="form-control" id="password" name="password" placeholder="密碼">
                </div>
            </div>
            <div class="form-group">
                <label for="password" class="col-sm-2 control-label">驗證碼</label>
                <div class="col-sm-10">
                    <input type="text" name="valid_code" id="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").click(function () {
        // 1. 取到用戶填寫的用戶名和密碼 -> 取input框的值
        var username = $("#username").val();
        var password = $("#password").val();
        var valid_code = $("#valid_code").val();
        // 2. 用AJAX發送到服務端
        $.ajax({
            url: "/login/",
            type: "post",
            data: {
                "username": username,
                "password": password,
                "valid_code": valid_code,
                "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()
            },
            success: function (data) {
                console.log(data);
                if (data.status) {
                    // 有錯誤,在頁面上提示
                    $(".login-error").text(data.msg);
                } else {
                    // 登陸成功
                    location.href = data.msg;
                }
            }
        })
    });

    // 當input框獲取焦點時將之前的錯誤清空
    $("#username,#password").focus(function () {
        // 將之前的錯誤清空
        $(".login-error").text("");
    });

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

 

 
 
        
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM