feat: 添加滑动验证码
This commit is contained in:
97
src/api/captcha/index.ts
Normal file
97
src/api/captcha/index.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import type { TicketInfoType, TokenInfoType } from 'react-rotate-captcha'
|
||||
import { handle } from './canvas'
|
||||
import wallhaven from '@/assets/images/wallhaven.jpg'
|
||||
export type ActionType = {
|
||||
code: 0 | 1
|
||||
msg: string
|
||||
}
|
||||
|
||||
const tokenRaw = 'Nvuv8LdXUNRAVW022Gm7HkGc7RTDoEmU'
|
||||
const info = {
|
||||
angle: -1,
|
||||
sid: '',
|
||||
ticket: '',
|
||||
}
|
||||
|
||||
export async function checkTicket(ticket?: TicketInfoType) {
|
||||
const { sid, ticket: ticketRaw } = info
|
||||
const { data } = ticket || {}
|
||||
|
||||
const isWait = sid !== '' && ticketRaw !== ''
|
||||
const success = sid === data?.sid && ticketRaw === data.ticket
|
||||
|
||||
const result =
|
||||
isWait && success
|
||||
? {
|
||||
code: 0,
|
||||
msg: 'Successful',
|
||||
}
|
||||
: {
|
||||
code: 1,
|
||||
msg: 'Failed',
|
||||
}
|
||||
|
||||
return result as ActionType
|
||||
}
|
||||
|
||||
export async function get(): Promise<TokenInfoType> {
|
||||
info.angle = -1
|
||||
info.sid = ''
|
||||
info.ticket = ''
|
||||
return {
|
||||
code: 0,
|
||||
data: {
|
||||
str: 'wallhaven',
|
||||
token: tokenRaw,
|
||||
},
|
||||
msg: 'success',
|
||||
}
|
||||
}
|
||||
|
||||
export function isSupportWebp() {
|
||||
try {
|
||||
return (
|
||||
document
|
||||
.createElement('canvas')
|
||||
.toDataURL('image/webp', 0.5)
|
||||
.indexOf('data:image/webp') === 0
|
||||
)
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export async function load() {
|
||||
const [degree, src] = await handle(wallhaven)
|
||||
info.angle = degree
|
||||
|
||||
return src
|
||||
}
|
||||
|
||||
export function sleep(time: number) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve(true), time)
|
||||
})
|
||||
}
|
||||
|
||||
export async function verify(token: string, deg: number): Promise<TicketInfoType> {
|
||||
const { angle } = info
|
||||
const success = token === tokenRaw && Math.abs(deg - angle) <= 5
|
||||
|
||||
info.sid = Math.random().toString(36).slice(-8)
|
||||
info.ticket = crypto.randomUUID()
|
||||
|
||||
return angle >= 0 && success
|
||||
? {
|
||||
code: 0,
|
||||
data: {
|
||||
sid: info.sid,
|
||||
ticket: info.ticket,
|
||||
},
|
||||
msg: 'Success',
|
||||
}
|
||||
: {
|
||||
code: 1,
|
||||
msg: 'Fail verify',
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user