topfans/frontend/utils/deviceFingerprint.js
2026-06-22 17:19:48 +08:00

53 lines
1.7 KiB
JavaScript
Raw Permalink 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.

/**
* 设备指纹spec §9.1 v2.3 限流维度 — X-Device-Fingerprint
*
* 为什么不复用 push ciduni.getPushClientId 拿到的 cid
* - push cid 在推送 SDK 升级 / 推送通道重连时会变 → 限流计数被误清零
* - 小程序/H5 端无 push 概念,多端不统一
*
* 方案App 启动时生成一次 UUID v4持久化到 storage
* - 跨重启 / 跨账号 / 推送 SDK 升级 → 稳定不变
* - 卸载重装后才会变storage 一起被清,业界无解)
*
* 自包含:第一次调用时自动 bootstrap无需外部初始化。
* 三端统一App / 小程序 / H5不依赖 plus.* 等平台 API。
*/
const STORAGE_KEY = 'deviceFp'
/**
* 获取当前设备的稳定指纹;首次调用时自动生成并写入 storage。
* @returns {string} UUID v4 格式字符串
*/
export function getDeviceFingerprint() {
let fp = ''
try {
fp = uni.getStorageSync(STORAGE_KEY)
} catch (e) {
// storage 读取失败时降级:本次返回临时值,下次调用会重试
}
if (!fp) {
fp = generateUuidV4()
try {
uni.setStorageSync(STORAGE_KEY, fp)
} catch (e) {
// storage 写入失败不影响本次使用(仅会下次重新生成)
console.warn('[deviceFingerprint] setStorageSync failed', e)
}
}
return fp
}
/**
* 生成 RFC4122 v4 格式 UUID。
* 使用 Math.random()uni-app 三端通用),不引入第三方库。
* 设备指纹场景对密码学强度无要求,唯一性即可。
*/
function generateUuidV4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0
const v = c === 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
}