feat: verification
This commit is contained in:
@@ -73,3 +73,18 @@ def send_excel(file_handler, file_name, suffix='xlsx'):
|
||||
attachment_filename='{}.{}'.format(file_name, suffix),
|
||||
as_attachment=True
|
||||
)
|
||||
|
||||
|
||||
def send_png(img_handler, name='image'):
|
||||
"""
|
||||
发送图片文件(可用于验证码)
|
||||
:param img_handler:
|
||||
:param name:
|
||||
:return:
|
||||
"""
|
||||
return send_file(
|
||||
img_handler,
|
||||
mimetype='image/png',
|
||||
attachment_filename='{}.png'.format(name),
|
||||
as_attachment=True
|
||||
)
|
||||
|
3
nc_http/core/verification/__init__.py
Normal file
3
nc_http/core/verification/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
用户验证码相关
|
||||
"""
|
38
nc_http/core/verification/image.py
Normal file
38
nc_http/core/verification/image.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import random
|
||||
import string
|
||||
from io import BytesIO
|
||||
|
||||
from captcha.image import ImageCaptcha
|
||||
|
||||
|
||||
class SimpleImageCaptcha:
|
||||
|
||||
def __init__(self, width=150, height=50, captcha_length=4, characters=string.digits, *args, **kwargs):
|
||||
self.__width = width
|
||||
self.__height = height
|
||||
self.__captcha_length = captcha_length
|
||||
self.__characters = characters
|
||||
|
||||
self.__str = ''.join([random.choice(characters) for _ in range(captcha_length)])
|
||||
|
||||
generator = ImageCaptcha(width=self.__width, height=self.__height, *args, **kwargs)
|
||||
self.__image = generator.create_captcha_image(
|
||||
chars=self.__str,
|
||||
color=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)),
|
||||
background=(255, 255, 255)
|
||||
)
|
||||
|
||||
@property
|
||||
def str(self):
|
||||
return self.__str
|
||||
|
||||
@property
|
||||
def image(self):
|
||||
return self.__image
|
||||
|
||||
@property
|
||||
def image_handler(self):
|
||||
output = BytesIO()
|
||||
self.__image.save(output, 'png')
|
||||
output.seek(0)
|
||||
return output
|
64
nc_http/core/verification/storage.py
Normal file
64
nc_http/core/verification/storage.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from abc import abstractmethod, ABC
|
||||
|
||||
from nc_http.core.verification.image import SimpleImageCaptcha
|
||||
|
||||
|
||||
class BaseCaptchaStorage(ABC):
|
||||
|
||||
@classmethod
|
||||
def create(cls, *args, **kwargs):
|
||||
"""
|
||||
创建验证码
|
||||
:return:
|
||||
"""
|
||||
captcha = SimpleImageCaptcha(*args, **kwargs)
|
||||
cls.storage(captcha.str)
|
||||
return captcha
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def storage(captcha_code):
|
||||
"""
|
||||
记录生成的验证码字符
|
||||
:param captcha_code:
|
||||
:return:
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def validate(captcha_code):
|
||||
"""
|
||||
确认验证码正确性
|
||||
:param captcha_code:
|
||||
:return: str
|
||||
"""
|
||||
|
||||
|
||||
class SampleCaptchaStorage(BaseCaptchaStorage):
|
||||
"""
|
||||
验证码池样例实现
|
||||
|
||||
* 仅作测试使用,勿用于生产环境
|
||||
"""
|
||||
storage_dict = {}
|
||||
|
||||
@staticmethod
|
||||
def storage(captcha_code):
|
||||
SampleCaptchaStorage.storage_dict[captcha_code] = True
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def validate(captcha_code):
|
||||
valid = SampleCaptchaStorage.storage_dict.get(captcha_code)
|
||||
if valid:
|
||||
del SampleCaptchaStorage.storage_dict[captcha_code]
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_captcha = SampleCaptchaStorage.create()
|
||||
is_valid = SampleCaptchaStorage.validate('test_code')
|
||||
print(is_valid)
|
||||
is_valid = SampleCaptchaStorage.validate(test_captcha.str)
|
||||
print(is_valid)
|
17
nc_http/tests/verification.py
Normal file
17
nc_http/tests/verification.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import unittest
|
||||
|
||||
from nc_http.core.verification.storage import SampleCaptchaStorage
|
||||
|
||||
|
||||
class VerificationTestCase(unittest.TestCase):
|
||||
|
||||
def test_storage(self):
|
||||
captcha = SampleCaptchaStorage.create()
|
||||
is_valid = SampleCaptchaStorage.validate('test_code')
|
||||
self.assertEqual(is_valid, False)
|
||||
is_valid = SampleCaptchaStorage.validate(captcha.str)
|
||||
self.assertEqual(is_valid, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user