一个开箱即用的滑动验证码React组件,基于[isszz/rotate-captcha]做的二次开发;结合了腾讯防水墙,增加安全策略,查看:设计思路
后端提供Laravel
扩展:levi/laravel-rotate-captcha
[查看],可直接使用或参考下方Api接口定制
![image](https://private-user-images.githubusercontent.com/578141/286532872-0f6d4073-2811-4c5b-807d-a95d56973848.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjUwODQwMzUsIm5iZiI6MTcyNTA4MzczNSwicGF0aCI6Ii81NzgxNDEvMjg2NTMyODcyLTBmNmQ0MDczLTI4MTEtNGM1Yi04MDdkLWE5NWQ1Njk3Mzg0OC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwODMxJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDgzMVQwNTU1MzVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT05Mzc5NjIzZGM2MGM3ZWU4NTU5ZmFkNjMzZjRlOTE2ZTQ2NWIzODU1OGY2NjUwM2ViOGIwYzBiMzUxMDY3MDBmJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.Mlkvcqyt4Z9IbHT8vJppdvGVW_KNAVqxvZwUZpKSGMg)
以下演示全部都一样,分别展示了多主题,多语言、多个唤起方式;在不同的环境下的演示,可根据自己的情况选择一个环境查看演示和演示的代码
- CodeSondbox:Webpack+TS+React [查看]
- CodeSondbox:Webpack+JS+React [查看]
- CodeSondbox:Vite+TS+React [查看]
- Stackblitz:ts+react [查看]
视频演示:
1701247930163032.mp4
Using NPM
npm install react-rotate-captcha
Using Yarn
yarn add react-rotate-captcha
Using PNPM
pnpm add react-rotate-captcha
通过status
唤起
import { useState } from 'react';
import RotateCaptcha from "react-rotate-captcha";
function App() {
const [open, setOpen] = useState(true);
return <RotateCaptcha open={open} onClose={() => setOpen(false)} />
}
通过Instance
唤起
import RotateCaptcha from "react-rotate-captcha";
function Page() {
const captcha = RotateCaptcha.useCaptchaInstance();
return (
<button onClick={() => captcha.open()}>click it</button>
);
}
function App() {
return (
<RotateCaptcha>
<Page />
</RotateCaptcha>
);
}
通过ref
唤起
import { useRef } from 'react';
import RotateCaptcha, { CaptchaInstance } from "react-rotate-captcha";
function App() {
const ref = useRef<CaptchaInstance>(null);
return (
<RotateCaptcha ref={ref}>
<button onClick={() => ref.current!.open()}>click it</button>
</RotateCaptcha>
);
}
更多请见下方Api
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
className | 验证浮窗顶层样式名,用于覆盖默认主题样式 | string |
- |
close | 自定义关闭按钮,设置null 屏蔽按钮 |
ReactNode │ null |
- |
lang | 语言,默认提供en 和zh_CN ,接受传入LangType 对象自定义语言 |
LangType │ string |
zh_CN |
limit | 试错次数,需要和服务端设置一致 | number |
2 |
mask | 自定义背景层,设置null 屏蔽背景层 |
ReactNode │ null |
- |
open | true 打开验证码,否则关闭 |
boolean |
- |
tips | 自定义底部提示 | ReactNode |
- |
theme | 提供两个主体dark 和light ,自定义主题通过自定义样式变量 |
string |
light |
zIndex | 浮窗样式层级 | number |
999 |
接受5个方法,只有onClose
和result
是同步函数,其余全部为异步函数
参数 | 说明 | 参数 | 返回值 |
---|---|---|---|
get | 初始获取验证码信息 | - | Promise<resultType<tokenType>> |
load | 提取tokenType 中的str 去换图片,返回图片URL 路径或图片base64 字符 |
path: string |
Promise<string> |
onClose | 关闭浮窗触发,以status 唤起的验证,必须提供onClose 来关闭 |
- | void |
result | 提取正确或错误的票据结果,可选,也可以通过verify 直接获取结果 |
info: resultType<ticketType> |
void |
verify | 滚动验证,返回票据信息 | token: string ,deg: number |
Promise<resultType<ticketType>> |
- Captcha数据类型:[查看]
- 请通过下方提供的
Api
接口,自行获取验证数据,组件内部不提供数据获取
通过ref
或useCaptchaInstance
返回的Captcha
实例,接受3个方法,所有方法都返回void
,具体如下:
参数 | 说明 | 参数 |
---|---|---|
close | 关闭浮窗,参数force 默认值false ,设为true 将强制销毁验证浮窗 |
force?: boolean |
open | 打开浮窗 | - |
reload | 重新获取验证码图片 | - |
- 通过
status
唤起的验证,不支持强制销毁
通过useContent
提供上下文CaptchaContext
,方便自定义提示栏:
CurrentlyType: [0|1|2|3|4, string, boolean?]
,验证状态:
- 状态:0.正确; 1.错误; 2.待获取; 3.待提交; 4.提交中
- 提示信息
- 是否强制停止流程,例如初始信息加载失败
LangType
使用的语言:[查看]
captcha
,Captcha实例,如果只获取实例建议通过ref
或useCaptchaInstance
这里以开源的levi/laravel-rotate-captcha
(查看)举例,提供了5个接口(查看),请求参数和返回数据如下:
- URL:
/rotate.captcha
- method:
GET
- response:
{ code: 0|1; msg: string; data: { ${str}: string } }
- res header:
X-Captchatoken: ${token}
- URL:
/rotate.captcha/${str}
- method:
GET
- response: image url or base64
- URL:
/rotate.captcha/verify/${angle}/${token?}
- method:
GET
- response:
{ code: 0|1|2; msg: string; data?: { ${sid}: string; ${ticket}: string; } }
- req header:
X-Captchatoken: ${token}
URL
中或req header
中的,至少有一处提供${token?}
- URL:
/rotate.captcha/test/action
- method:
GET|POST
- response:
{ code: 0|1|2; msg: string; }
- req header:
X-Captchasid: ${sid}; X-Captchaticket: ${ticket}; X-Captchapolicie?: ${police}
请求可以通过header
或POST formData
或POST raw
提交;安全策略police
根据服务器配置决定是否提交
当需要匹配不同尺寸的设备时,或者一些老的设备不支持webp
的情况下,通过这个接口获取定制的验证图片
- URL:
/rotate.captcha
- method:
POST
- formData:
{ size?: number; output?: 'jpg'|'png'|'webp' }
- response:
{ code: 0|1; msg: string; data: { ${str}: string } }
- res header:
X-Captchatoken: ${token}
code
的状态:0.正常; 1.错误可继续; 2.错误重新开始; 注意:小于0的值为内部保留状态,请勿使用
如果安装后获取不到组件类型,请在tsconfig.json
的compilerOptions
添加如下引导:
"typeRoots": [
"./node_modules/@types"
]
安全策略详细见laravel-rotate-captcha
[查看],在提供允许的情况下,前端发送X-Captchapolici
这个header
,申请对应的权限。
高级用法:
- 验证流程中
ua
实际并不局限使用User-Agent
,可以通过自定义头部加密拼接增加安全系数 - 除了头部,包括图片路径,都可以在本地通过二次加密
encryption
的方式增加安全系数
即时设计的向量稿件,包含组件设计规范:查看
具体请查看文档:更新日志
后端提供Laravel
扩展:levi/laravel-rotate-captcha
[查看],可直接使用或参考上方Api接口定制
第三方仓库,提供了react和laravel之外的生态扩展 [点击打开]
包含:
- 前端:vue、uni-app
- 后端:php、ThinkPHP
基于react实现的滑动验证码组件 [点击打开]