修复打手短信验证码发送
This commit is contained in:
@@ -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()
|
||||
Reference in New Issue
Block a user