圖片驗(yàn)證碼
1. 分析
前端發(fā)送圖片uuid,后端生成圖片,返回前端
2. 請(qǐng)求方式
request: GET
3. 接口URL路徑定義
url: /captcha_codes/<uuid:captcha_uuid>/
4. 前端傳遞參數(shù)方式及數(shù)據(jù)格式
傳遞參數(shù)方式:url 路徑參數(shù)傳參
| 參數(shù) | 類型 | 前端是否必須傳 | 描述 |
|---|---|---|---|
| captcha_uuid | uuid字符串 | 是 | 圖片驗(yàn)證碼編號(hào) |
uuid:Universally unique identifier(eg. 123e4567-e89b-12d3-a456-426655440000)
5.代碼實(shí)現(xiàn)
- 后端代碼
- 配置 verifications app
- 生成 manage.py@Dreamblog > startapp verifications
manage.py@Dreamblog > startapp verifications- 注冊(cè)
INSTALLED_APPS = [ # ... 'verifications', ]- 導(dǎo)入路徑
urlpatterns = [ # ... path('verifications/', include('verifications.urls')), ] - 將 圖像驗(yàn)證碼的模塊文件夾(captcha文件夾)復(fù)制粘貼到項(xiàng)目根目錄utils文件夾下
- 安裝圖片驗(yàn)證碼所需要的 Pillow 模塊 pip install Pillow
- 確保settings.py文件中有配置redis CACHE
Redis原生指令參考 http://redisdoc.com/index.html
Redis python客戶端 方法參考 http://redis-py.readthedocs.io/en/latest/#indices-and-tables
# 配置redis緩存 # 在settings.py文件中指定redis配置 CACHES = { # 默認(rèn)redis數(shù)據(jù)庫(kù) -- default "default": { "BACKEND": "django_redis.cache.RedisCache", # 引擎 "LOCATION": "redis://127.0.0.1:6379/0", # 0 代表第一個(gè)數(shù)據(jù)庫(kù),端口默認(rèn)6379 "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } }, # 指定redis數(shù)據(jù)庫(kù) -- "verify_codes" # 保存圖片以及短信驗(yàn)證碼 "verify_codes": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", # 1 代表第一個(gè)數(shù)據(jù)庫(kù), "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } }, }- 代碼實(shí)現(xiàn)
- 配置 verifications app
# views.py
import logging
from django.views import View
from django.http import HttpResponse
from django_redis import get_redis_connection
from . import constants
from utils.captcha.captcha import captcha
logger =logging.getLogger('django')
# 圖片驗(yàn)證碼視圖
class CaptchaView(View):
"""
1.創(chuàng)建一個(gè)類視圖: CaptchaView
2.明確請(qǐng)求方式: GET
3.url路徑定義: /captcha_codes/<uuid:captcha_uuid>/
4.前端傳參方式及參數(shù):
-- 傳參方式: url路徑傳參,
-- 參數(shù): captcha_uuid
5.獲取前端參數(shù):
-- get(self, request, captcha_uuid)
6.業(yè)務(wù)處理:
-- 1.是否需要校驗(yàn)以及校驗(yàn)方式 不需要,url路徑傳參已校驗(yàn)
-- 2.是否需要儲(chǔ)存以及儲(chǔ)存方式 需要,redis儲(chǔ)存
-- 3.其他 利用uuid生成圖片驗(yàn)證碼
7.返回前端參數(shù):
-- return HttpResponse(content=captcha_content, content_type='image/jpg')
"""
def get(self, request, captcha_uuid):
"""
:param request:
:param captcha_uuid:
:return:
"""
# 利用接口,生成圖片驗(yàn)證碼文本以及二進(jìn)制文件
captcha_text, captcha_content = captcha.generate_captcha()
# redis 保存數(shù)據(jù)三部曲
# 1. 連接redis
conn_redis = get_redis_connection(alias="verify_codes")
# 2. 建立key值 -- key值設(shè)為二進(jìn)制
captcha_key = 'captcha_{}'.format(captcha_uuid).encode('utf-8')
# 3. 保存數(shù)據(jù),并設(shè)置有效期
conn_redis.setex(captcha_key, constants.CAPTCHA_CODE_REDIS_EXPIRES, captcha_text)
# 日志器記錄,后臺(tái)顯示
logger.info('圖片驗(yàn)證碼為:{}'.format(captcha_text))
# 返回前端參數(shù),驗(yàn)證碼二進(jìn)制文件
# type='image/jpg'默認(rèn)打開, type='images/jpg'默認(rèn)下載
return HttpResponse(content=captcha_content, content_type='image/jpg')
# constants.py
# 圖片驗(yàn)證碼redis有效期,單位秒
CAPTCHA_CODE_REDIS_EXPIRES = 5 * 60
# urls.py
from django.urls import path
from . import views
app_name = 'verifications'
urlpatterns = [
path('captcha_codes/<uuid:captcha_uuid>/', views.CaptchaView.as_view(), name='captcha_code'),
]
-
postman測(cè)試
image.png redis數(shù)據(jù)庫(kù)查看數(shù)據(jù)
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> keys *
1) "captcha_123e4567-e89b-12d3-a456-426655440000"
127.0.0.1:6379[1]> ttl "captcha_123e4567-e89b-12d3-a456-426655440000"
(integer) 183
127.0.0.1:6379[1]>
6.前端代碼
register.html代碼
<a href="javascript:void(0);" class="captcha-graph-img">
<img src="" alt="" title="點(diǎn)擊刷新" class="captcha_image">
</a>
{% block script %}
<script src="{% static 'js/users/register.js' %}"></script>
{% endblock %}
在js文件夾下創(chuàng)建一個(gè)users文件夾用戶存放用戶模塊相關(guān)的js文件,在users文件下創(chuàng)建users.js文件
// -----------------register.js--------------------- //
$(function () {
// -----------------圖像驗(yàn)證碼邏輯代碼--------------------- //
let $captcha = $('.captcha_image'); // 獲取圖像標(biāo)簽
let s_UUID = ''; // 定義圖像驗(yàn)證碼ID值
let s_captcha_url= ''; // 定義獲取圖像驗(yàn)證碼 url
// 生成圖像驗(yàn)證碼圖片
generateImageCode();
// 點(diǎn)擊圖片驗(yàn)證碼生成新的圖片驗(yàn)證碼圖片
$captcha.click(generateImageCode);
// 生成請(qǐng)求驗(yàn)證碼 url
function generateImageCode() {
// 1、生成一個(gè)圖片驗(yàn)證碼隨機(jī)編號(hào)
s_UUID = generateUUID();
// 2、拼接請(qǐng)求url verifications/captcha_codes/<uuid:captcha_uuid>/
s_captcha_url = '/verifications/captcha_codes/' + s_UUID + '/';
// 3、修改驗(yàn)證碼圖片src地址(此時(shí)后端傳入圖片二進(jìn)制,顯示)
$captcha.attr('src',s_captcha_url)
}
// 生成圖片UUID驗(yàn)證碼
function generateUUID() {
let d = new Date().getTime();
if (window.performance && typeof window.performance.now === "function") {
d += performance.now(); //use high-precision timer if available
}
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
}
});
展示

image_1.png

image_2.png
127.0.0.1:6379[1]> keys *
1) "captcha_9cdb9550-b409-4dc9-aa35-52b865f19108"
2) "captcha_fcb8934b-8086-48f2-a712-de1b9b1ab516"
3) "captcha_034ea509-5423-4d9d-a074-e996366af401"
4) "captcha_09aef28e-22ef-4587-b37a-77acb4376a57"
5) "captcha_85b481da-f926-4182-b474-7c2324be351f"
6) "captcha_d58f4beb-a9a3-4e8b-8c4f-979c7a96acea"
7) "captcha_abf202b8-63f8-4e68-b3af-5f234c2c7342"
