https://github.com/lloydzhou/pow-captcha
simple pow-captcha server based on redis-module and openressty
https://github.com/lloydzhou/pow-captcha
capture openresty pow redis-module
Last synced: 3 months ago
JSON representation
simple pow-captcha server based on redis-module and openressty
- Host: GitHub
- URL: https://github.com/lloydzhou/pow-captcha
- Owner: lloydzhou
- Created: 2025-05-12T04:00:10.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-05-20T08:45:14.000Z (about 1 year ago)
- Last Synced: 2025-05-20T09:47:22.534Z (about 1 year ago)
- Topics: capture, openresty, pow, redis-module
- Language: C
- Homepage:
- Size: 55.7 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# PoW Captcha Service
## English
This project provides a lightweight, efficient, and simple Proof-of-Work (PoW) captcha service. It is built using a custom Redis module, OpenResty, and corresponding JavaScript code.
The Redis module supports the following three commands:
1. `POW.CHALLENGE `: Creates a new PoW challenge.
2. `POW.VERIFY `: Verifies a PoW solution.
3. `POW.TOKEN `: Checks if a verification token is valid.
OpenResty acts as a wrapper around the Redis module, exposing HTTP endpoints for the captcha functionality, while the JavaScript handles the client-side PoW computation.
This setup offers a simple yet effective way to protect your services from bots.
---
## Quick Start
docker run -p 8888:80 lloydzhou/pow-captcha
---
## Usage Example
There are multiple ways to integrate the PoW Captcha:
**1. Automatic Rendering (Recommended)**
The easiest way is to declare a `div` element in your HTML with the class `pow-captcha`. The SDK will automatically find these divs, render a hidden `input` field within them, and populate it with the PoW token.
```html
POWCaptcha Auto Render Demo
// Optional callback functions
function myCaptchaSuccessCallback(token) {
console.log('Captcha success, token:', token);
// You can handle the token here, e.g., enable a submit button
document.getElementById('submit-button').disabled = false;
}
function myCaptchaErrorCallback(error) {
console.error('Captcha failed:', error);
// You can handle the error here
}
Username:
Loading captcha...
Submit
// When the form is submitted, the hidden input (pow-captcha-token) will be submitted with it
// document.getElementById('myForm').addEventListener('submit', function(event) {
// const tokenInput = this.querySelector('input[name="pow-captcha-token"]');
// if (!tokenInput || !tokenInput.value) {
// event.preventDefault(); // Prevent submission if no token (optional)
// alert('Please wait for the captcha to complete.');
// }
// });
```
The `pow-captcha` `div` supports the following `data-*` attributes:
- `data-callback`: (Optional) The name of a global JavaScript function to call upon successful PoW. The token will be passed as its first argument.
- `data-error-callback`: (Optional) The name of a global JavaScript function to call upon PoW failure. The error object will be passed as its first argument.
- `data-timeout`: (Optional) Timeout in milliseconds for the PoW challenge. Defaults to 30000 (30 seconds).
- `data-endpoint`: (Optional) The base URL of your PoW Captcha service. Defaults to the origin of `sdk.js`.
**2. Manual Rendering**
If you need more fine-grained control, you can call the `window.POW.render(containerElement, options)` function.
```html
POWCaptcha Manual Render Demo
function myCallback(token) {
console.log('Manual render success, token:', token);
document.getElementById('token-display').innerText = 'Token obtained: ' + token;
}
function myErrorCallback(error) {
console.error('Manual render failed:', error);
document.getElementById('token-display').innerText = 'Failed to obtain token: ' + error.message;
}
// Execute after DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
const captchaContainer = document.getElementById('my-captcha-container');
if (captchaContainer) {
window.POW.render(captchaContainer, {
// Options object is similar to the POW() function's
// timeout: 45000, // milliseconds
// endpoint: 'http://your-pow-service.com'
// Note: If data-callback, data-error-callback, data-timeout, data-endpoint are present on the container element,
// they will override options passed here unless not defined in options.
// For clarity, define callbacks either via data-* attributes or solely via options.
});
}
});
```
The second argument to `window.POW.render`, the `options` object, is similar to the `options` object for the `window.POW()` function described below. Additionally, `data-*` attributes on the container element (like `data-callback`, `data-timeout`) are also considered and will generally take precedence over corresponding settings in the `options` object if present.
**3. Calling `POW()` Directly**
You can also call the `window.POW()` function directly. It returns a Promise that resolves with the PoW token upon success.
```html
POWCaptcha Demo
// Call the POW function
// You can pass options like endpoint and timeout
// e.g., window.POW({ endpoint: 'http://your-pow-captcha-service.com', timeout: 60000 })
window.POW().then(function(token) {
console.log('POWCaptcha token:', token);
// Use the token to verify on your backend
// For example, make an AJAX request to your server with this token
// fetch('/your-protected-endpoint', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// 'X-POW-TOKEN': token
// },
// body: JSON.stringify({ /* your data */ })
// });
document.write(`<h3>Successfully obtained POWCaptcha token: ${token}</h3>`);
// For demonstration, this opens a new tab to verify the token directly with the PoW service
// In a real application, you would send this token to your backend for verification.
// Your backend would then call the /token endpoint of the PoW service.
// window.open('/token?token=' + token, '_blank');
}).catch(function(error) {
console.error('POWCaptcha error:', error);
document.write(`<h3>Failed to obtain POWCaptcha token: ${error.message}</h3>`);
});
```
The `POW()` function accepts an optional `options` object:
- `endpoint`: (Optional) The base URL of your PoW Captcha service. Defaults to the origin of `sdk.js`.
- `timeout`: (Optional) Timeout in milliseconds for the PoW challenge. Defaults to 30000 (30 seconds).
On your server-side, when a user submits a form or performs an action protected by PoW Captcha, you should take the received token (for automatic or manual rendering, it's typically in a hidden input named `pow-captcha-token`) and verify it by making a request to the `/token?token=` endpoint of your PoW Captcha service. If the service responds with "VALID", the token is good.