Package Exports
- react-next-captcha
- react-next-captcha/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-next-captcha) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
react-next-captcha
A simple and customizable captcha generator and verifier for Node.js, designed to be used with React and Next.js applications. Built on top of svg-captcha, it provides an easy way to add captchas to your web application without the need for Google reCAPTCHA or C++ addons.
Features
- Generates SVG captchas
- Customizable options for captcha size, noise, and characters
- Secure verification with custom salts
- Easy integration with Next.js and React
Installation
Install the package using npm:
npm install react-next-captchaBasic Setup - (Next.js)
A) Server-Side (Next.js API Routes)
Create API routes to generate and verify captchas:
pages/api/generate-captcha.jsimport { createCaptcha } from 'react-next-captcha'; export default function handler(req, res) { const { size, noise, ignoreChars } = req.body; const options = { size: size || 6, noise: noise || 2, ignoreChars: ignoreChars || '0o1ilIL', }; // Custom salt const customSalt = 'your_custom_salt'; const captcha = createCaptcha(options, customSalt); res.status(200).json({ captcha: captcha.data, hash: captcha.hash }); }
pages/api/verify-captcha.jsimport { checkCaptcha } from 'react-next-captcha'; export default function handler(req, res) { const { text, hash } = req.body; const result = checkCaptcha(text, hash); res.status(200).json(result); }
B) Client-Side (React Component)
Create a React component to display and refresh the captcha:
/index.js
import { useState } from 'react';
const Captcha = () => {
const [captcha, setCaptcha] = useState('');
const [hash, setHash] = useState('');
const fetchCaptcha = async () => {
const response = await fetch('/api/generate-captcha', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
});
const data = await response.json();
setCaptcha(data.captcha);
setHash(data.hash);
};
return (
<div>
<div dangerouslySetInnerHTML={{ __html: captcha }} />
<button onClick={fetchCaptcha}>Generate Captcha</button>
{/* Use the hash for verification */}
<p>Hash: {hash}</p>
</div>
);
};
export default Captcha;Advanced Configuration
Customizing Captcha Options
You can customize various options when generating the captcha:
size: Size of the random string (default: 6)ignoreChars: Characters to exclude from the captcha (default: '0o1ilIL')noise: Number of noise lines (default: 2)color: Characters will have distinct colors instead of grey (default: false)background: Background color of the SVG image (default: transparent)
Example with Custom Options
pages/api/generate-captcha.js
import { createCaptcha } from 'react-next-captcha';
export default function handler(req, res) {
const { size, noise, ignoreChars, color, background } = req.body;
const options = {
size: size || 6,
noise: noise || 2,
ignoreChars: ignoreChars || '0o1ilIL',
color: color || false,
background: background || '#ffffff',
};
// Custom salt
const customSalt = 'your_custom_salt';
const captcha = createCaptcha(options, customSalt);
res.status(200).json({ captcha: captcha.data, hash: captcha.hash });
}Verifying Captcha
To verify a captcha, use the checkCaptcha function. Pass the text entered by the user and the hash received when generating the captcha.
pages/api/verify-captcha.js
import { checkCaptcha } from 'react-next-captcha';
export default function handler(req, res) {
const { text, hash } = req.body;
const result = checkCaptcha(text, hash);
res.status(200).json(result);
}Integration with Next.js and React
Here's how you can integrate the react-next-captcha package with your Next.js and React application.
Step 1: Install the package
npm install react-next-captchaStep 2: Create API routes for generating and verifying captchas
Refer to the server-side integration section above for creating the API routes.
Step 3: Create a React component to display the captcha
Refer to the client-side integration section above for creating the Captcha component.
API
svgCaptcha.create(options): Create a captcha with options.size: Size of random string (default: 4)ignoreChars: Characters to exclude from captcha (default: '0o1i')noise: Number of noise lines (default: 1)color: Characters will have distinct colors instead of grey (default: false)background: Background color of the SVG image (default: transparent)- Returns an object with
data(SVG path data) andtext(captcha text).
svgCaptcha.createMathExpr(options): Create a math expression captcha with options.- Additional options include
mathMin,mathMax, andmathOperator.
- Additional options include
svgCaptcha.loadFont(url): Load a custom font.svgCaptcha.options: Global setting object for default options.svgCaptcha.randomText([size|options]): Return a random string.svgCaptcha(text, options): Return an SVG captcha based on provided text.
Integrates in NextJs
let's create a Next.js application with a login page that integrates react-next-captcha and includes captcha reloading and verification upon form submission.
Step 1: Set Up Next.js Application
First, create a new Next.js application if you don't already have one:
npx create-next-app@latest my-next-app
cd my-next-appInstall the required packages:
npm install react-next-captcha
npm install axiosStep 2: Create API Routes
Create the API routes to generate and verify captchas.
pages/api/generate-captcha.js
import { createCaptcha } from 'react-next-captcha';
export default function handler(req, res) {
const { size, noise, ignoreChars } = req.body;
const options = {
size: size || 6,
noise: noise || 2,
ignoreChars: ignoreChars || '0o1ilIL',
};
// Custom salt
const customSalt = 'your_custom_salt';
const captcha = createCaptcha(options, customSalt);
res.status(200).json({ captcha: captcha.data, hash: captcha.hash });
}pages/api/verify-captcha.js
import { checkCaptcha } from 'react-next-captcha';
export default function handler(req, res) {
const { text, hash } = req.body;
const result = checkCaptcha(text, hash);
res.status(200).json(result);
}Step 3: Create Login Component
Create a React component for the login page, including the captcha.
pages/login.js
import { useState } from 'react';
import axios from 'axios';
const Login = () => {
const [captcha, setCaptcha] = useState('');
const [hash, setHash] = useState('');
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [captchaInput, setCaptchaInput] = useState('');
const [error, setError] = useState('');
const fetchCaptcha = async () => {
const response = await axios.post('/api/generate-captcha');
setCaptcha(response.data.captcha);
setHash(response.data.hash);
};
const handleSubmit = async (e) => {
e.preventDefault();
const response = await axios.post('/api/verify-captcha', {
text: captchaInput,
hash,
});
if (response.data.success) {
// Proceed with login
// For demonstration purposes, we'll just log the user details
console.log('Username:', username);
console.log('Password:', password);
setError('');
// Here you can add the logic to handle the actual login, e.g., an API call to your backend
} else {
setError('Captcha verification failed. Please try again.');
fetchCaptcha();
}
};
return (
<div>
<h1>Login</h1>
<form onSubmit={handleSubmit}>
<div>
<label>
Username:
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
required
/>
</label>
</div>
<div>
<label>
Password:
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</label>
</div>
<div>
<div dangerouslySetInnerHTML={{ __html: captcha }} />
<button type="button" onClick={fetchCaptcha}>
Reload Captcha
</button>
</div>
<div>
<label>
Captcha:
<input
type="text"
value={captchaInput}
onChange={(e) => setCaptchaInput(e.target.value)}
required
/>
</label>
</div>
{error && <p style={{ color: 'red' }}>{error}</p>}
<div>
<button type="submit">Login</button>
</div>
</form>
</div>
);
};
export default Login;Step 4: Initial Fetch of Captcha
Modify the useEffect hook in the Login component to fetch the captcha initially when the component mounts.
import { useState, useEffect } from 'react';
import axios from 'axios';
const Login = () => {
const [captcha, setCaptcha] = useState('');
const [hash, setHash] = useState('');
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [captchaInput, setCaptchaInput] = useState('');
const [error, setError] = useState('');
useEffect(() => {
fetchCaptcha();
}, []);
const fetchCaptcha = async () => {
const response = await axios.post('/api/generate-captcha', {
size: 6,
noise: 2,
ignoreChars: '0o1ilIL',
});
setCaptcha(response.data.captcha);
setHash(response.data.hash);
};
const handleSubmit = async (e) => {
e.preventDefault();
const response = await axios.post('/api/verify-captcha', {
text: captchaInput,
hash,
});
if (response.data.success) {
// Proceed with login
// For demonstration purposes, we'll just log the user details
console.log('Username:', username);
console.log('Password:', password);
setError('');
// Here you can add the logic to handle the actual login, e.g., an API call to your backend
} else {
setError('Captcha verification failed. Please try again.');
fetchCaptcha();
}
};
return (
<div>
<h1>Login</h1>
<form onSubmit={handleSubmit}>
<div>
<label>
Username:
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
required
/>
</label>
</div>
<div>
<label>
Password:
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</label>
</div>
<div>
<div dangerouslySetInnerHTML={{ __html: captcha }} />
<button type="button" onClick={fetchCaptcha}>
Reload Captcha
</button>
</div>
<div>
<label>
Captcha:
<input
type="text"
value={captchaInput}
onChange={(e) => setCaptchaInput(e.target.value)}
required
/>
</label>
</div>
{error && <p style={{ color: 'red' }}>{error}</p>}
<div>
<button type="submit">Login</button>
</div>
</form>
</div>
);
};
export default Login;Step 5: Start the Next.js Application
Run the Next.js application:
npm run devWhy Use SVG?
- Does not require any C++ addon.
- Resulting image is smaller than JPEG image.
- Harder for captcha recognition software to decode.