修复打手短信验证码发送

This commit is contained in:
yml2213
2026-08-02 15:12:02 +08:00
parent c138d75d8e
commit 2227cda73d
19 changed files with 1010 additions and 36 deletions
+91
View File
@@ -0,0 +1,91 @@
import crypto from 'node:crypto'
import https from 'node:https'
import { runtimeConfig } from '../src/config/runtime.js'
function percentEncode(value: string): string {
return encodeURIComponent(String(value || ''))
.replace(/\+/g, '%20')
.replace(/\*/g, '%2A')
.replace(/%7E/g, '~')
}
function signAliyunRequest(params: Record<string, string>, accessKeySecret: string): string {
const canonicalizedQuery = Object.entries(params)
.map(([key, value]) => `${percentEncode(key)}=${percentEncode(value)}`)
.sort((left, right) =>
String(left[0]) < String(right[0]) ? -1 : String(left[0]) > String(right[0]) ? 1 : 0,
)
.join('&')
const stringToSign = `GET&${percentEncode('/')}&${percentEncode(canonicalizedQuery)}`
const hmac = crypto.createHmac('sha1', `${accessKeySecret}&`)
hmac.update(stringToSign)
return hmac.digest('base64')
}
async function main() {
const config = runtimeConfig.worker.sms
console.log('当前短信配置:')
console.log(' provider :', config.provider)
console.log(' accessKeyId :', config.accessKeyId ? `${config.accessKeyId.slice(0, 4)}...${config.accessKeyId.slice(-4)}` : '(空)')
console.log(' accessKeySecret :', config.accessKeySecret ? `${config.accessKeySecret.slice(0, 4)}...${config.accessKeySecret.slice(-4)}(长度 ${config.accessKeySecret.length}` : '(空)')
console.log(' signName :', config.signName)
console.log(' templateCode :', config.templateCode)
console.log('')
if (!config.accessKeyId || !config.accessKeySecret || !config.signName || !config.templateCode) {
console.error('配置不完整,请检查 .env 中的 WORKER_SMS_* 配置')
return
}
const phone = process.argv[2] || '13800000000'
const params: Record<string, string> = {
AccessKeyId: config.accessKeyId,
Action: 'SendSms',
Format: 'JSON',
Version: '2017-05-25',
SignatureMethod: 'HMAC-SHA1',
SignatureVersion: '1.0',
SignatureNonce: crypto.randomUUID(),
Timestamp: new Date().toISOString().replace(/\.\d{3}Z$/, 'Z'),
PhoneNumbers: phone,
SignName: config.signName,
TemplateCode: config.templateCode,
TemplateParam: JSON.stringify({ code: '123456' }),
}
const signature = signAliyunRequest(params, config.accessKeySecret)
params.Signature = signature
const queryString = Object.entries(params)
.map(([key, value]) => `${percentEncode(key)}=${percentEncode(value)}`)
.sort()
.join('&')
const url = `https://dysmsapi.aliyuncs.com/?${queryString}`
console.log('stringToSign:')
console.log(' ', `GET&%2F&${percentEncode(
Object.entries(params)
.filter(([key]) => key !== 'Signature')
.map(([key, value]) => `${percentEncode(key)}=${percentEncode(value)}`)
.sort((left, right) => (String(left[0]) < String(right[0]) ? -1 : String(left[0]) > String(right[0]) ? 1 : 0))
.join('&'),
)}`)
console.log('')
console.log(`发送测试短信到 ${phone}(验证码 123456...`)
https
.get(url, (response) => {
const chunks: Buffer[] = []
response.on('data', (chunk) => chunks.push(Buffer.from(chunk)))
response.on('end', () => {
const body = Buffer.concat(chunks).toString('utf8')
console.log('响应:', body)
})
})
.on('error', (error) => {
console.error('请求失败:', error.message)
})
}
void main()