Files
web/src/actions/auth/verify.ts

71 lines
1.6 KiB
TypeScript
Raw Normal View History

2025-03-19 15:49:18 +08:00
'use server'
// 验证验证码函数
import {cookies} from 'next/headers'
import crypto from 'crypto'
import {ApiResponse} from '@/lib/api'
import { callByDevice } from '@/actions/base'
2025-03-19 15:49:18 +08:00
export interface VerifyParams {
2025-03-28 15:00:46 +08:00
phone: string
captcha: string // 添加验证码字段
2025-03-19 15:49:18 +08:00
}
export default async function verify(props: VerifyParams): Promise<ApiResponse> {
try {
// 人机验证
if (!props.captcha?.length) {
return {
success: false,
status: 400,
message: '请输入验证码',
}
}
const valid = await verifyCaptcha(props.captcha)
if (!valid) {
return {
success: false,
status: 400,
message: '验证码错误或已过期',
}
}
// 请求发送短信
return await callByDevice('/api/auth/verify/sms', {
2025-03-19 15:49:18 +08:00
phone: props.phone,
purpose: 0,
})
}
catch (error) {
throw new Error('验证码验证失败', {cause: error})
}
}
async function verifyCaptcha(userInput: string): Promise<boolean> {
const cookieStore = await cookies()
const hash = cookieStore.get('captcha_hash')?.value
const salt = cookieStore.get('captcha_salt')?.value
// 如果没有找到验证码cookie验证失败
if (!hash || !salt) {
return false
}
// 使用相同的方法哈希用户输入的验证码
const userInputHash = crypto
.createHmac('sha256', salt)
.update(userInput.toLowerCase())
.digest('hex')
// 比较哈希值
const isValid = hash === userInputHash
// 验证后删除验证码cookie防止重复使用
if (isValid) {
cookieStore.delete('captcha_hash')
cookieStore.delete('captcha_salt')
}
return isValid
}