Files
order_site/apps/backend/scripts/verify-aliyun-sms.ts
T

92 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()