欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Python實(shí)現(xiàn)原生的登錄驗(yàn)證碼詳情

 更新時(shí)間:2021年10月15日 09:21:46   作者:山山仙人博客  
在前面的文章中,我有分享到 vue+drf+第三方滑動(dòng)驗(yàn)證碼接入的實(shí)現(xiàn),本文將要分享的是基于 python 實(shí)現(xiàn)原生的登錄驗(yàn)證碼,需要的朋友可以參考一下

1、概述

在前面的文章中,我有分享了vue+drf+第三方滑動(dòng)驗(yàn)證碼接入的實(shí)現(xiàn) (文中也留了分享圖片驗(yàn)證碼功能的實(shí)現(xiàn)),即本文將要分享的是基于 python 實(shí)現(xiàn)原生的登錄驗(yàn)證碼

通常的驗(yàn)證碼,人眼看上去更像是一張小圖片

html 語法中,嵌入一張圖片一般用 img 標(biāo)簽實(shí)現(xiàn),而 img 標(biāo)簽對(duì)應(yīng)的 src 一般有以下幾種寫法

  • 圖片的本地路徑
  • 圖片的url
  • 圖片的二進(jìn)制數(shù)據(jù)(base64編碼)

其中前兩種方法都需要外部具有實(shí)際存在的圖片,第三種方法則是將圖片進(jìn)行編碼后填充到 img 標(biāo)簽的 src

2、驗(yàn)證碼實(shí)現(xiàn)的演進(jìn)過程

2.1 路由及頁面

為了實(shí)現(xiàn)驗(yàn)證碼的功能,需要開設(shè)一個(gè) url 單獨(dú)處理驗(yàn)證碼功能,修改全局路由

urlpatterns = [
    ......
    url(r'^login/', views.login, name='login'),
    # 圖片驗(yàn)證碼
    url(r'^get_code/', views.get_code, name='gc'),
    ...
]

然后修改前端登錄頁面 login.html 的驗(yàn)證碼部分

...
<div class="form-group">
    <label for="">驗(yàn)證碼</label>
    <div class="row">
        <div class="col-md-6">
            <input type="text" name="code" id="id_code" class="form-control">
        </div>
        <div class="col-md-6">
            <img src="/get_code/" alt="" width="430" height="35" id="id_img">
        </div>
    </div>

</div>
<input type="button" class="btn btn-success" value="登陸" id="id_commit">
...

2.2 視圖函數(shù)中驗(yàn)證碼的推導(dǎo)

2.2.1 圖片發(fā)送到前端

前端界面實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的包含驗(yàn)證碼的登錄框,首先定義一個(gè)視圖函數(shù)將后端的測(cè)試圖片以二進(jìn)制的形式發(fā)送到前端進(jìn)行測(cè)試

def get_code(request):
    # 直接獲取后端現(xiàn)成的圖片二進(jìn)制數(shù)據(jù)發(fā)送給前端
    with open(r'static/img/test.jpg','rb') as f:
        data = f.read()
    return HttpResponse(data)


2.2.2 引入動(dòng)態(tài)圖片

為了操作圖片,主要利用的是 pillow 模塊

pip3 install pillow


主要用到了 Image 、 ImageDraw 、 ImageFont

  • Image:生成圖片
  • ImageDraw:在圖片上定義內(nèi)容
  • ImageFont:控制字體樣式

因此,利用 pillow 模塊動(dòng)態(tài)產(chǎn)生圖片的方法為

import random
from PIL import Image, ImageDraw, ImageFont

def get_random():
    return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)


def get_code(request):
    # 利用pillow模塊動(dòng)態(tài)產(chǎn)生圖片
    # img_obj = Image.new('RGB',(430,35),'green')  # RGB組合、圖片尺寸、顏色
    img_obj = Image.new('RGB',(430,35),get_random())  # 通過色值指定顏色
    # 先將圖片對(duì)象保存起來
    with open('xxx.png','wb') as f:
        img_obj.save(f,'png')
    # 再將圖片對(duì)象讀取出來
    with open('xxx.png','rb') as f:
        data = f.read()
    return HttpResponse(data)

2.2.3 內(nèi)存管理模塊圖片

上面將圖片對(duì)象保存在讀取有些麻煩,文件存儲(chǔ)繁瑣 IO 操作效率低 ,可以借助于內(nèi)存管理器模塊實(shí)現(xiàn)

其中又分為 BytesIO StringIO 兩種

  • BytesIO:臨時(shí)存儲(chǔ)數(shù)據(jù),返回的時(shí)候數(shù)據(jù)是二進(jìn)制
  • StringIO:臨時(shí)存儲(chǔ)數(shù)據(jù),返回的時(shí)候數(shù)據(jù)是字符串

內(nèi)存管理對(duì)象就相當(dāng)于上面的文件句柄

import random
from PIL import Image, ImageDraw, ImageFont

def get_random():
    return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)


def get_code(request):
    img_obj = Image.new('RGB', (430, 35), get_random())
    io_obj = BytesIO()  # 生成一個(gè)內(nèi)存管理器對(duì)象  你可以看成是文件句柄
    img_obj.save(io_obj,'png')
    return HttpResponse(io_obj.getvalue())  # 從內(nèi)存管理器中讀取二進(jìn)制的圖片數(shù)據(jù)返回給前端

這樣一來,圖片的生成以及返回就比較友好了

2.2.4 完整圖片驗(yàn)證碼

上面解決了圖片如何傳遞到前端頁面的問題,剩下的就是如何生成對(duì)應(yīng)的隨機(jī)驗(yàn)證碼了

例如隨機(jī)驗(yàn)證碼為五位數(shù)的隨機(jī)驗(yàn)證碼,包含數(shù)字、小寫字母、大寫字母

import random
from PIL import Image, ImageDraw, ImageFont

def get_random():
    return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)


def get_code(request):
    # 寫圖片驗(yàn)證碼
    img_obj = Image.new('RGB', (430, 35), get_random())
    img_draw = ImageDraw.Draw(img_obj)  # 產(chǎn)生一個(gè)畫筆對(duì)象
    # 引入本地的字體文件,指定字體樣式及字體大小
    img_font = ImageFont.truetype('static/font/222.ttf', 30) 
    # 隨機(jī)驗(yàn)證碼 五位數(shù)的隨機(jī)驗(yàn)證碼  數(shù)字 小寫字母 大寫字母
    code = ''
    for i in range(5):
        random_upper = chr(random.randint(65, 90))  # 隨機(jī)大寫字母
        random_lower = chr(random.randint(97, 122))  # 隨機(jī)小寫字母
        random_int = str(random.randint(0, 9))  # 隨機(jī)數(shù)字
        # 每次從上面三個(gè)里面隨機(jī)選擇一個(gè)
        tmp = random.choice([random_lower, random_upper, random_int])
        # 將產(chǎn)生的隨機(jī)字符串寫入到圖片上,需要調(diào)整每個(gè)字體所在的坐標(biāo)變換
        img_draw.text((i * 60 + 60, -2), tmp, get_random(), img_font)
        # 拼接隨機(jī)字符串
        code += tmp
    print(code)
    # 隨機(jī)驗(yàn)證碼在登陸的視圖函數(shù)里面需要要比對(duì),所以要找地方存起來并且其他視圖函數(shù)也能拿到
    request.session['code'] = code
    io_obj = BytesIO()
    img_obj.save(io_obj, 'png')
    return HttpResponse(io_obj.getvalue())

這里有一點(diǎn),在寫入隨機(jī)文字的時(shí)候一個(gè)個(gè)寫而不是生成好了之后再寫,是因?yàn)橐粋€(gè)個(gè)寫能夠控制每個(gè)字體的間隙。而生成好之后再寫的話,間隙就沒法控制了

2.3 登錄驗(yàn)證中使用驗(yàn)證碼

上面將每次生成的驗(yàn)證碼存儲(chǔ)到了 session 中,這樣在前端傳過來的驗(yàn)證碼,登錄校驗(yàn)時(shí)就可以進(jìn)行比對(duì)了

......
def login(request):
    if request.method == 'POST':
        back_dic = {'code': 1000, 'msg': ''}
        username = request.POST.get('username')
        password = request.POST.get('password')
        code = request.POST.get('code')
        # 1 先校驗(yàn)驗(yàn)證碼是否正確  自己決定是否忽略大小寫 統(tǒng)一轉(zhuǎn)大寫或小寫再比較
        if request.session.get('code').upper() == code.upper():
            # 校驗(yàn)用戶名和密碼是否正確
            user_obj = auth.authenticate(request,username=username,password=password)
            if user_obj:
                # 保存用戶狀態(tài)
                auth.login(request,user_obj)
                back_dic['url'] = '/home/'
            else:
                back_dic['code'] = 2000
                back_dic['msg'] = '用戶名或密碼錯(cuò)誤'
        else:
            back_dic['code'] = 3000
            back_dic['msg'] = '驗(yàn)證碼錯(cuò)誤'
        return JsonResponse(back_dic)
    return render(request, 'login.html')

2.4 前端頁面點(diǎn)擊自動(dòng)刷新

最后,還留下一點(diǎn)小問題,前端在輸入驗(yàn)證碼錯(cuò)誤后不會(huì)自動(dòng)刷新,如果點(diǎn)擊驗(yàn)證碼也不會(huì)進(jìn)行刷新,只能通過刷新登錄頁面才能刷新驗(yàn)證碼,因此需要想辦法讓用戶在點(diǎn)擊驗(yàn)證碼時(shí)自動(dòng)刷新(單獨(dú)觸發(fā)驗(yàn)證碼的視圖函數(shù))

每次在點(diǎn)擊時(shí),修改對(duì)應(yīng) src 的值即可,可以通過一小段 js 實(shí)現(xiàn)

...
       <div class="form-group">
            <label for="">驗(yàn)證碼</label>

            <div class="row">
                <div class="col-md-6">
                    <input type="text" name="code" id="id_code" class="form-control">
                </div>
                <div class="col-md-6">
                    <img src="/get_code/" alt="" width="430" height="35" id="id_img">
                </div>
            </div>

        </div>
        <input type="button" class="btn btn-success" value="登陸" id="id_commit">
...
<script>
    $("#id_img").click(function () {
        // 獲取標(biāo)簽之前的src
        let oldVal = $(this).attr('src');
        $(this).attr('src',oldVal += '?')
    })
</script>

3、效果展示

最終前端的驗(yàn)證碼效果如圖

4、小結(jié)

本文基于 python 以及相關(guān)的庫(kù)原生實(shí)現(xiàn)了登錄驗(yàn)證碼邏輯~

其實(shí)寫本文也是因?yàn)橹坝羞^想法但是一段時(shí)間就忘了,最近通過某銀行手機(jī)銀行 app 重置登錄密碼的時(shí)候,發(fā)現(xiàn)其驗(yàn)證碼顯示效果和本文效果竟然神似~,于是撿起來寫了此文

其手機(jī) app 驗(yàn)證碼效果如下

 到此這篇關(guān)于基于Python實(shí)現(xiàn)原生的登錄驗(yàn)證碼詳情的文章就介紹到這了,更多相關(guān)基于Python實(shí)現(xiàn)原生的登錄驗(yàn)證碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python動(dòng)態(tài)網(wǎng)頁批量爬取

    python動(dòng)態(tài)網(wǎng)頁批量爬取

    這篇文章主要介紹了python動(dòng)態(tài)網(wǎng)頁批量爬取的方法,主要針對(duì)四六級(jí)成績(jī)批量爬取,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 為什么說python適合寫爬蟲

    為什么說python適合寫爬蟲

    在本文中,小編給讀者們整理的一篇關(guān)于分析為什么說python適合寫爬蟲的語言的相關(guān)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2020-06-06
  • 基于python連接oracle導(dǎo)并出數(shù)據(jù)文件

    基于python連接oracle導(dǎo)并出數(shù)據(jù)文件

    這篇文章主要介紹了基于python連接oracle導(dǎo)并出數(shù)據(jù)文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 解決python報(bào)錯(cuò):AttributeError:?'ImageDraw'?object?has?no?attribute?'textbbox'

    解決python報(bào)錯(cuò):AttributeError:?'ImageDraw'?object?h

    這篇文章主要給大家介紹了關(guān)于解決python報(bào)錯(cuò):AttributeError:?'ImageDraw'?object?has?no?attribute?'textbbox'的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • python如何利用traceback獲取詳細(xì)的異常信息

    python如何利用traceback獲取詳細(xì)的異常信息

    異常信息的獲取對(duì)于程序的調(diào)試非常重要,可以有助于快速定位有錯(cuò)誤程序語句的位置。這篇文章主要給大家介紹了關(guān)于python如何利用traceback獲取詳細(xì)的異常信息的相關(guān)資料,需要的朋友可以參考下
    2021-06-06
  • Python格式化壓縮后的JS文件的方法

    Python格式化壓縮后的JS文件的方法

    這篇文章主要介紹了Python格式化壓縮后的JS文件的方法,實(shí)例分析了Python格式化文件的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • python借助ChatGPT讀取.env實(shí)現(xiàn)文件配置隔離保障私有數(shù)據(jù)安全

    python借助ChatGPT讀取.env實(shí)現(xiàn)文件配置隔離保障私有數(shù)據(jù)安全

    這篇文章主要為大家介紹了python讀取.env實(shí)現(xiàn)文件配置隔離保障私有數(shù)據(jù)安全,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Python爬蟲框架Scrapy實(shí)戰(zhàn)之批量抓取招聘信息

    Python爬蟲框架Scrapy實(shí)戰(zhàn)之批量抓取招聘信息

    網(wǎng)絡(luò)爬蟲又被稱為網(wǎng)頁蜘蛛,網(wǎng)絡(luò)機(jī)器人,在FOAF社區(qū)中間,更經(jīng)常的稱為網(wǎng)頁追逐者,是按照一定的規(guī)則,自動(dòng)抓取萬維網(wǎng)信息的程序或者腳本。這篇文章主要介紹Python爬蟲框架Scrapy實(shí)戰(zhàn)之批量抓取招聘信息,有需要的朋友可以參考下
    2015-08-08
  • python opencv常用圖形繪制方法(線段、矩形、圓形、橢圓、文本)

    python opencv常用圖形繪制方法(線段、矩形、圓形、橢圓、文本)

    這篇文章主要介紹了python opencv常用圖形繪制方法(線段、矩形、圓形、橢圓、文本),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 解決jupyter notebook 出現(xiàn)In[*]的問題

    解決jupyter notebook 出現(xiàn)In[*]的問題

    這篇文章主要介紹了解決jupyter notebook 出現(xiàn)In[*]的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04

最新評(píng)論