Simple JWT with Captcha2
========================
.. image:: https://jazzband.co/static/img/badge.svg
:target: https://jazzband.co/
:alt: Jazzband
.. image:: https://github.com/jazzband/djangorestframework-simplejwt/workflows/Test/badge.svg
:target: https://github.com/jazzband/djangorestframework-simplejwt/actions
:alt: GitHub Actions
.. image:: https://codecov.io/gh/jazzband/djangorestframework-simplejwt/branch/master/graph/badge.svg
:target: https://codecov.io/gh/jazzband/djangorestframework-simplejwt
.. image:: https://img.shields.io/pypi/v/djangorestframework-simplejwt.svg
:target: https://pypi.python.org/pypi/djangorestframework-simplejwt
.. image:: https://img.shields.io/pypi/pyversions/djangorestframework-simplejwt.svg
:target: https://pypi.python.org/pypi/djangorestframework-simplejwt
.. image:: https://img.shields.io/pypi/djversions/djangorestframework-simplejwt.svg
:target: https://pypi.python.org/pypi/djangorestframework-simplejwt
.. image:: https://readthedocs.org/projects/django-rest-framework-simplejwt/badge/?version=latest
:target: https://django-rest-framework-simplejwt.readthedocs.io/en/latest/
Abstract
--------
Simple JWT with Captcha2 是对 `djangorestframework-simplejwt` 的二次开发版本,在原有 JWT 登录认证基础上,增加了图形验证码(CAPTCHA)验证逻辑,用于增强登录安全性。
它适用于需要在登录时加入验证码验证的 Django REST Framework 项目。
Installation
------------
使用 pip 安装:
.. code-block:: bash
pip install djangorestframework_simplejwt_captcha2
Usage
-----
在你的 Django 设置文件中配置 ``INSTALLED_APPS`` 参数,例如:
.. code-block:: python
INSTALLED_APPS = [
'rest_framework_simplejwt',
]
在你的 Django 项目的 URL 配置中添加如下路径:
.. code-block:: python
from rest_framework_simplejwt.views import (
captcha_verify,
login_captcha_verify,
token_refresh,
token_verify,
token_obtain_pair
)
urlpatterns = [
path('api/token/', token_obtain_pair, name='token_pair'),
path('api/token/refresh/', token_refresh, name='token_refresh'),
path('api/token/verify/', token_verify, name='token_verify'),
path('api/captcha/', captcha_verify, name='captcha'),
path('api/login/', login_captcha_verify, name='login_captcha'),
]
接口说明:
- ``/api/captcha/``:获取验证码图片(Base64)和唯一标识 UUID。
响应示例:
.. code-block:: json
{
"uuid": "abc123xyz",
"img": "data:image/png;base64,iVBORw0KG..."
}
- ``/api/token/``:普通登录接口,返回 JWT Token(当不需要验证码时使用)。
请求参数:
.. code-block:: json
{
"username": "your_username",
"password": "your_password"
}
- ``/api/login/``:带验证码的登录接口,需传入用户名、密码、UUID 和 Base64 图片内容。
请求参数:
.. code-block:: json
{
"username": "your_username",
"password": "your_password",
"uuid": "abc123xyz",
"img": "data:image/png;base64,iVBORw0KG..."
}
- ``/api/token/refresh/``:刷新 Access Token。
请求参数:
.. code-block:: json
{
"refresh": "your_refresh_token"
}
- ``/api/token/verify/``:验证 Token 是否有效。
请求参数:
.. code-block:: json
{
"token": "your_access_token"
}
Settings
--------
在你的 Django 设置文件中配置 ``SIMPLE_JWT`` 参数,例如:
.. code-block:: python
SIMPLE_JWT = {
# ...其他配置...
# 验证码类型支持 'calculation' 或 'number'
# calculation 仅支持 + - * 运算
"CAPTCHA_TYPE": "calculation",
# 验证码过期时间(秒),默认为 120 秒
"CAPTCHA_CACHE_TIME": 120,
# 仅在 CAPTCHA_TYPE 为 'number' 时生效,默认长度为 4
"CAPTCHA_LENGTH": 4,
# 验证码默认宽度 185
"CAPTCHA_WIDTH": 185,
# 验证码默认高度 40
"CAPTCHA_HEIGHT": 40,
# ...其他配置...
}
Translations
------------
本项目支持多语言翻译,可通过 Django 的 i18n 功能进行扩展。
Documentation
-------------
完整文档请访问:
🔗 https://django-rest-framework-simplejwt-captcha2.readthedocs.io/en/latest/
License
-------
MIT License.
Source Code
-----------
GitHub 地址:🔗 https://github.com/yaohua1179/djangorestframework_simplejwt_captcha2
Raw data
{
"_id": null,
"home_page": "https://github.com/yaohua1179/djangorestframework_simplejwt_captcha2",
"name": "djangorestframework-simplejwt-captcha2",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "djangorestframework_simplejwt_captcha2",
"author": "Qinghua.yao",
"author_email": "yaohua1179@163.com",
"download_url": "https://files.pythonhosted.org/packages/b3/63/2fc28101affc83a0888095ca779a488478eb7f6485e8ff91b52fca817cad/djangorestframework_simplejwt_captcha2-0.0.9.tar.gz",
"platform": null,
"description": "Simple JWT with Captcha2\r\n========================\r\n.. image:: https://jazzband.co/static/img/badge.svg\r\n :target: https://jazzband.co/\r\n :alt: Jazzband\r\n.. image:: https://github.com/jazzband/djangorestframework-simplejwt/workflows/Test/badge.svg\r\n :target: https://github.com/jazzband/djangorestframework-simplejwt/actions\r\n :alt: GitHub Actions\r\n.. image:: https://codecov.io/gh/jazzband/djangorestframework-simplejwt/branch/master/graph/badge.svg\r\n :target: https://codecov.io/gh/jazzband/djangorestframework-simplejwt\r\n.. image:: https://img.shields.io/pypi/v/djangorestframework-simplejwt.svg\r\n :target: https://pypi.python.org/pypi/djangorestframework-simplejwt\r\n.. image:: https://img.shields.io/pypi/pyversions/djangorestframework-simplejwt.svg\r\n :target: https://pypi.python.org/pypi/djangorestframework-simplejwt\r\n.. image:: https://img.shields.io/pypi/djversions/djangorestframework-simplejwt.svg\r\n :target: https://pypi.python.org/pypi/djangorestframework-simplejwt\r\n.. image:: https://readthedocs.org/projects/django-rest-framework-simplejwt/badge/?version=latest\r\n :target: https://django-rest-framework-simplejwt.readthedocs.io/en/latest/\r\n\r\nAbstract\r\n--------\r\n\r\nSimple JWT with Captcha2 \u662f\u5bf9 `djangorestframework-simplejwt` \u7684\u4e8c\u6b21\u5f00\u53d1\u7248\u672c\uff0c\u5728\u539f\u6709 JWT \u767b\u5f55\u8ba4\u8bc1\u57fa\u7840\u4e0a\uff0c\u589e\u52a0\u4e86\u56fe\u5f62\u9a8c\u8bc1\u7801\uff08CAPTCHA\uff09\u9a8c\u8bc1\u903b\u8f91\uff0c\u7528\u4e8e\u589e\u5f3a\u767b\u5f55\u5b89\u5168\u6027\u3002\r\n\r\n\u5b83\u9002\u7528\u4e8e\u9700\u8981\u5728\u767b\u5f55\u65f6\u52a0\u5165\u9a8c\u8bc1\u7801\u9a8c\u8bc1\u7684 Django REST Framework \u9879\u76ee\u3002\r\n\r\nInstallation\r\n------------\r\n\r\n\u4f7f\u7528 pip \u5b89\u88c5\uff1a\r\n\r\n.. code-block:: bash\r\n\r\n pip install djangorestframework_simplejwt_captcha2\r\n\r\nUsage\r\n-----\r\n\r\n\u5728\u4f60\u7684 Django \u8bbe\u7f6e\u6587\u4ef6\u4e2d\u914d\u7f6e ``INSTALLED_APPS`` \u53c2\u6570\uff0c\u4f8b\u5982\uff1a\r\n\r\n.. code-block:: python\r\n\r\n INSTALLED_APPS = [\r\n 'rest_framework_simplejwt',\r\n ]\r\n\r\n\r\n\u5728\u4f60\u7684 Django \u9879\u76ee\u7684 URL \u914d\u7f6e\u4e2d\u6dfb\u52a0\u5982\u4e0b\u8def\u5f84\uff1a\r\n\r\n.. code-block:: python\r\n\r\n from rest_framework_simplejwt.views import (\r\n captcha_verify,\r\n login_captcha_verify,\r\n token_refresh,\r\n token_verify,\r\n token_obtain_pair\r\n )\r\n\r\n urlpatterns = [\r\n path('api/token/', token_obtain_pair, name='token_pair'),\r\n path('api/token/refresh/', token_refresh, name='token_refresh'),\r\n path('api/token/verify/', token_verify, name='token_verify'),\r\n path('api/captcha/', captcha_verify, name='captcha'),\r\n path('api/login/', login_captcha_verify, name='login_captcha'),\r\n ]\r\n\r\n\u63a5\u53e3\u8bf4\u660e\uff1a\r\n\r\n- ``/api/captcha/``\uff1a\u83b7\u53d6\u9a8c\u8bc1\u7801\u56fe\u7247\uff08Base64\uff09\u548c\u552f\u4e00\u6807\u8bc6 UUID\u3002\r\n\r\n \u54cd\u5e94\u793a\u4f8b\uff1a\r\n\r\n .. code-block:: json\r\n\r\n {\r\n \"uuid\": \"abc123xyz\",\r\n \"img\": \"data:image/png;base64,iVBORw0KG...\"\r\n }\r\n\r\n- ``/api/token/``\uff1a\u666e\u901a\u767b\u5f55\u63a5\u53e3\uff0c\u8fd4\u56de JWT Token\uff08\u5f53\u4e0d\u9700\u8981\u9a8c\u8bc1\u7801\u65f6\u4f7f\u7528\uff09\u3002\r\n\r\n \u8bf7\u6c42\u53c2\u6570\uff1a\r\n\r\n .. code-block:: json\r\n\r\n {\r\n \"username\": \"your_username\",\r\n \"password\": \"your_password\"\r\n }\r\n\r\n- ``/api/login/``\uff1a\u5e26\u9a8c\u8bc1\u7801\u7684\u767b\u5f55\u63a5\u53e3\uff0c\u9700\u4f20\u5165\u7528\u6237\u540d\u3001\u5bc6\u7801\u3001UUID \u548c Base64 \u56fe\u7247\u5185\u5bb9\u3002\r\n\r\n \u8bf7\u6c42\u53c2\u6570\uff1a\r\n\r\n .. code-block:: json\r\n\r\n {\r\n \"username\": \"your_username\",\r\n \"password\": \"your_password\",\r\n \"uuid\": \"abc123xyz\",\r\n \"img\": \"data:image/png;base64,iVBORw0KG...\"\r\n }\r\n\r\n- ``/api/token/refresh/``\uff1a\u5237\u65b0 Access Token\u3002\r\n\r\n \u8bf7\u6c42\u53c2\u6570\uff1a\r\n\r\n .. code-block:: json\r\n\r\n {\r\n \"refresh\": \"your_refresh_token\"\r\n }\r\n\r\n- ``/api/token/verify/``\uff1a\u9a8c\u8bc1 Token \u662f\u5426\u6709\u6548\u3002\r\n\r\n \u8bf7\u6c42\u53c2\u6570\uff1a\r\n\r\n .. code-block:: json\r\n\r\n {\r\n \"token\": \"your_access_token\"\r\n }\r\n\r\nSettings\r\n--------\r\n\r\n\u5728\u4f60\u7684 Django \u8bbe\u7f6e\u6587\u4ef6\u4e2d\u914d\u7f6e ``SIMPLE_JWT`` \u53c2\u6570\uff0c\u4f8b\u5982\uff1a\r\n\r\n.. code-block:: python\r\n\r\n SIMPLE_JWT = {\r\n # ...\u5176\u4ed6\u914d\u7f6e...\r\n\r\n # \u9a8c\u8bc1\u7801\u7c7b\u578b\u652f\u6301 'calculation' \u6216 'number'\r\n # calculation \u4ec5\u652f\u6301 + - * \u8fd0\u7b97\r\n \"CAPTCHA_TYPE\": \"calculation\",\r\n\r\n # \u9a8c\u8bc1\u7801\u8fc7\u671f\u65f6\u95f4\uff08\u79d2\uff09\uff0c\u9ed8\u8ba4\u4e3a 120 \u79d2\r\n \"CAPTCHA_CACHE_TIME\": 120,\r\n\r\n # \u4ec5\u5728 CAPTCHA_TYPE \u4e3a 'number' \u65f6\u751f\u6548\uff0c\u9ed8\u8ba4\u957f\u5ea6\u4e3a 4\r\n \"CAPTCHA_LENGTH\": 4,\r\n\r\n # \u9a8c\u8bc1\u7801\u9ed8\u8ba4\u5bbd\u5ea6 185\r\n \"CAPTCHA_WIDTH\": 185,\r\n\r\n # \u9a8c\u8bc1\u7801\u9ed8\u8ba4\u9ad8\u5ea6 40\r\n \"CAPTCHA_HEIGHT\": 40,\r\n\r\n # ...\u5176\u4ed6\u914d\u7f6e...\r\n }\r\n\r\nTranslations\r\n------------\r\n\r\n\u672c\u9879\u76ee\u652f\u6301\u591a\u8bed\u8a00\u7ffb\u8bd1\uff0c\u53ef\u901a\u8fc7 Django \u7684 i18n \u529f\u80fd\u8fdb\u884c\u6269\u5c55\u3002\r\n\r\nDocumentation\r\n-------------\r\n\r\n\u5b8c\u6574\u6587\u6863\u8bf7\u8bbf\u95ee\uff1a\r\n\r\n\ud83d\udd17 https://django-rest-framework-simplejwt-captcha2.readthedocs.io/en/latest/\r\n\r\nLicense\r\n-------\r\n\r\nMIT License.\r\n\r\nSource Code\r\n-----------\r\n\r\nGitHub \u5730\u5740\uff1a\ud83d\udd17 https://github.com/yaohua1179/djangorestframework_simplejwt_captcha2\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A minimal JSON Web Token authentication plugin for Django REST Framework",
"version": "0.0.9",
"project_urls": {
"Homepage": "https://github.com/yaohua1179/djangorestframework_simplejwt_captcha2"
},
"split_keywords": [
"djangorestframework_simplejwt_captcha2"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "6252e6fb80364a97adfaca75e898439abd9008023dd69fcdc8586bf5accc3c20",
"md5": "94ff5485e70073e91baa81e737c2611d",
"sha256": "776f4670e71d2d7acaaa477145144522f1c54180153d6e9635ff628f79a52f5b"
},
"downloads": -1,
"filename": "djangorestframework_simplejwt_captcha2-0.0.9-py3-none-any.whl",
"has_sig": false,
"md5_digest": "94ff5485e70073e91baa81e737c2611d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 110578,
"upload_time": "2025-07-16T06:46:49",
"upload_time_iso_8601": "2025-07-16T06:46:49.949239Z",
"url": "https://files.pythonhosted.org/packages/62/52/e6fb80364a97adfaca75e898439abd9008023dd69fcdc8586bf5accc3c20/djangorestframework_simplejwt_captcha2-0.0.9-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b3632fc28101affc83a0888095ca779a488478eb7f6485e8ff91b52fca817cad",
"md5": "f87199e437ff65225bdd8d7805f609ca",
"sha256": "6edaa0dbbfba347634cbb1da9424efb3427534998b3e4d40e5b24b8921fe5698"
},
"downloads": -1,
"filename": "djangorestframework_simplejwt_captcha2-0.0.9.tar.gz",
"has_sig": false,
"md5_digest": "f87199e437ff65225bdd8d7805f609ca",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 102681,
"upload_time": "2025-07-16T06:46:52",
"upload_time_iso_8601": "2025-07-16T06:46:52.732983Z",
"url": "https://files.pythonhosted.org/packages/b3/63/2fc28101affc83a0888095ca779a488478eb7f6485e8ff91b52fca817cad/djangorestframework_simplejwt_captcha2-0.0.9.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-16 06:46:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "yaohua1179",
"github_project": "djangorestframework_simplejwt_captcha2",
"github_not_found": true,
"lcname": "djangorestframework-simplejwt-captcha2"
}