A simple and minimal microservice for generating and validating CAPTCHA.
miniCAP is a simple microservice, written in Python, with only two REST endpoints:
one for creating CAPTCHAs (/api/captcha/generate/
) and one for verifying them
(/api/captcha/validate/
).
Some random samples of CAPTCHAs generated with miniCAP:
Light theme | Dark theme | |
---|---|---|
Only text | wFKdfr |
N9sx2G |
Text + background noise |
A4G9bu |
D46JLk |
Text + foreground noise |
Sx6pU7 |
3mtNKE |
Text + background noise + foreground noise |
MdEMFd |
95ScZ5 |
There are two ways of getting a working copy of miniCAP on your own computer: either
by using Docker or by using directly the source code
in a Python 3
(at least 3.10
) environment. In both cases, the first thing to do is
to get a local copy of this repository, so open up a terminal in the directory where you
want to save the project and clone the repository:
$ git clone https://github.com/ClaudiuGeorgiu/miniCAP.git
This is the suggested way of installing miniCAP, since the only requirement is to have a recent version of Docker installed:
$ docker --version
Docker version 20.10.22, build 3a2c30b
The official miniCAP Docker image is available on Docker Hub (automatically built from this repository):
$ # Download the Docker image.
$ docker pull claudiugeorgiu/minicap
$ # Give it a shorter name.
$ docker tag claudiugeorgiu/minicap minicap
If you downloaded the official image from Docker Hub, you are ready to use the service,
otherwise execute the following command in the previously created miniCAP/
directory
(the folder containing the Dockerfile
) to build the Docker image:
$ # Make sure to run the command in miniCAP/ directory.
$ # It will take some time to download and install all the dependencies.
$ docker build -t minicap .
miniCAP is now ready to be used, run the following command to start the service on port
8000
:
$ docker run --rm -p 8000:8000 minicap
miniCAP microservice is now running, see the usage instructions for more information.
The only requirement of this project is a working Python 3
(at least 3.10
)
installation (along with its package manager pip
).
Run the following commands in the main directory of the project (miniCAP/
) to
install the needed dependencies:
$ # Make sure to run the commands in miniCAP/ directory.
$ # The usage of a virtual environment is highly recommended.
$ python3 -m venv venv
$ source venv/bin/activate
$ # Install miniCAP's requirements.
$ python3 -m pip install -r requirements.txt
miniCAP is now ready to be used, run the following command to start the service on port
8000
:
$ # Make sure to run the command in miniCAP/ directory.
$ python3 -m minicap.main
miniCAP microservice is now running, see the usage instructions for more information.
When miniCAP microservice is running, it exposes only two REST endpoints for interacting with CAPTCHAs:
-
POST
/api/captcha/generate/
- returns a new CAPTCHA image in the response body (of typeimage/png
) and aCaptcha-Id
header needed to validate the CAPTCHA. This endpoint needsPOST
instead ofGET
requests because every request generates a newCaptcha-Id
that is saved into the database (GET
requests should be idempotent). -
POST
/api/captcha/validate/
- validates a CAPTCHA by accepting a request containing a previously generatedCaptcha-Id
and the text displayed in the CAPTCHA. The request must be a JSON containing a text fieldid
with the value ofCaptcha-Id
header and a text fieldtext
with the solution of the CAPTCHA.
Tip
While the microservice is running, the complete REST OpenAPI documentation is available at http://localhost:8000/docs.
Note
Each CAPTCHA is deleted from the database after:
- 10 minutes since its creation
- a successful validation
- 3 unsuccessful validation requests
-
Request the generation of a new CAPTCHA image and save the result into a file (e.g.,
CAPTCHA.png
). Take note of the value ofCaptcha-Id
response header, as it will be needed later for the validation request:$ curl -v -s -X POST "http://localhost:8000/api/captcha/generate/" --output CAPTCHA.png * ... < HTTP/1.1 200 OK < captcha-id: 1cc70567-8124-40f8-ba74-062c896f1535 < ...
-
Open the file with the CAPTCHA and solve it (e.g., the image displays the string
X575u6
). -
Send the CAPTCHA solution and the value of
Captcha-Id
header back to the server for validation:$ curl -X POST "http://localhost:8000/api/captcha/validate/" \ -H "Content-Type: application/json" \ -d '{ "id": "1cc70567-8124-40f8-ba74-062c896f1535", "text": "X575u6" }' {"status":200,"message":"CAPTCHA validated successfully"}%
import requests
# 1. Generate CAPTCHA and retrieve its id from Captcha-Id header.
res = requests.post("http://localhost:8000/api/captcha/generate/")
res.raise_for_status()
captcha_id = res.headers.get("Captcha-Id")
with open("CAPTCHA.png", "wb") as img:
img.write(res.content)
# 2. Open CAPTCHA image and solve it.
solution = "captcha solution here"
# 3. Validate CAPTCHA.
res = requests.post(
"http://localhost:8000/api/captcha/validate/",
json={"id": captcha_id, "text": solution},
)
res.raise_for_status()
Run the following command in the main directory of the project (miniCAP/
) to install
the test dependencies (needed only the first time):
$ python3 -m pip install -r requirements.test.txt
Then run the following command to execute the automatic test suite:
$ python3 -m pytest --verbose
Questions, bug reports and pull requests are welcome on GitHub at https://github.com/ClaudiuGeorgiu/miniCAP.
You are free to use this code under the MIT License.