手机号被自动关联到所有已登录账号后,开发者该改什么

设备端的号码验证机制默认开启,验证通过的号码会被加到这台设备上所有已登录账号里。关掉开关只阻止后续关联,已经关联上的号码仍留在各账号里,要逐个去个人信息页手动移除。用户在账号里看到的手机号,未必是他逐个确认填进去的。对开发者的影响集中在两处,号码作为账号标识的假设要重新审视,设备标识符的选型要更谨慎。

手机号在账号体系里实际承担什么

同一个号码往往同时扮演三个角色,它是对外的身份标识,找回密码时收验证码,风控时判断设备归属。三个角色的失效方式完全不同。

  • 作为标识,它假设号码和人的对应关系稳定。
  • 作为找回通道,它假设用户始终能收到这个号码的短信。
  • 作为风控信号,它假设换号等于换人。

运营商回收号码再分配会打破第一个假设,这是已确认的行业现实,但没有公开统计能说明比例。换不换号取决于用户,后两个假设随之失效。用户注销账号或长期停用,号码被回收再发给别人,新用户就可能收到本该属于原用户的验证码。

Android ID 的隔离范围和变化条件

从 Android 8.0 开始,ANDROID_ID 是一个 64 位十六进制字符串,取值按签名密钥、用户、设备三者组合隔离。同一台设备上,不同签名密钥的应用拿到不同值,多个用户各自独立。恢复出厂会变,更换 APK 签名密钥会变。设备升级到 Android 8.0 之前就已安装的应用,卸载重装会导致值改变,想跨卸载保留要自己用 Key/Value Backup 存一份。

它可以作为应用安装实例的稳定标识,不能当用户的长期身份。用户重装、清除数据、恢复出厂都会让它变,写进账号主键会让用户数据孤立丢失。

广告 ID 的可重置性和权限要求

广告 ID 由用户重置,重置后拿到新值,选择退出个性化后会得到一串零。从 targetSdk 33 开始,读取它需要声明 AD_ID 权限。 这里有条容易踩的红线。用户重置后,不允许用另一个标识符或设备指纹把新的广告 ID 和旧数据接续起来,也不允许把广告 ID 和个人身份信息关联。两套表用 account_id 直接连接是明显违规,即使连接字段看起来无害,比如设备型号加时间戳这类准标识符,在足够稀疏的事件上仍能重新关联。

合规要改的是数据模型,不是加密方式。把广告 ID 相关的表和个人信息表分开,访问控制列表保持独立,需要同时访问两类数据的人尽量少。

应用能拿到什么,拿不到什么

硬件标识符这条路基本封闭。IMEI 和序列号属于不可重置的标识符,从 Android 10 起普通应用读不到,需要设备所有者或配置文件所有者身份、特殊运营商权限,或者 READ_PRIVILEGED_PHONE_STATE 特权权限。

取本机号码的接口返回空字符串就表示不可用,这是明确的官方约定。空串可能意味着没有 SIM 卡、没有运营商权限,或者用户关闭了号码共享。安全敏感场景必须把空串当失败处理。

开发者该改哪几件事

  1. 账号主键不用手机号或 ANDROID_ID。用服务端生成的不可变内部 ID,手机号和设备标识符都作为可替换属性挂在账号上。
  2. 找回流程加多渠道备选。短信之外提供恢复码、邮箱或已登录设备的确认,避免单点号码失效导致账号永久失守。
  3. 换号要走显式流程。用户主动更换绑定号码时走一次完整验证,不让自动关联悄悄完成。
  4. 风控模型里手机号和设备标识符分开用。换号不等于换人,不要绑成同一个特征。

常见问题

换手机号会丢账号数据吗? 不会,前提是主键不是手机号。主键是内部 ID 的账号,换号只影响找回通道,更新绑定即可。

广告 ID 重置后还能归因吗? 不能把重置前后的数据接起来,这是政策红线。需要长期归因的场景改用自有账号体系或安装 ID。