'use server' import {ApiResponse} from '@/lib/api' import {callByDevice} from '@/actions/base' import {cookies} from 'next/headers' import crypto from 'crypto' export async function sendSMS(props: { phone: string captcha: string }): Promise { try { // 人机验证 if (!props.captcha?.length) { return { success: false, status: 400, message: '请输入验证码', } } const valid = await checkCaptcha(props.captcha) if (!valid) { return { success: false, status: 400, message: '验证码错误或已过期', } } // 请求发送短信 return await callByDevice('/api/auth/verify/sms', { phone: props.phone, purpose: 0, }) } catch (error) { console.error('验证码验证失败:', error) throw new Error('验证码验证失败', {cause: error}) } } export async function checkCaptcha(userInput: string): Promise { const cookieStore = await cookies() const hash = cookieStore.get('captcha_hash')?.value const salt = cookieStore.get('captcha_salt')?.value // 如果没有找到验证码cookie,验证失败 if (!hash || !salt) { console.log('验证码cookie不存在') 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 }