本节摘要:HarmonyOS 权限分 system_grant 与 user_grant 两类,敏感权限需运行时弹窗申请;本节走通申请代码与配置,并给出传输、存储、日志三环节的安全纪律清单,涵盖加密通道、安全存储与最小化原则。
从一次真实翻车讲起。给备忘录加"拍照贴到笔记"的功能,开发者写好了相机调用,模拟器上一切正常,真机上一点就崩,日志提示权限未授予。原因:相机属于 user_grant 类敏感权限,仅声明不够,必须在运行时向用户申请,被拒后还要引导。
这个场景浓缩了权限体系的全部要点。先建分类框架:
| 类别 | 授予方式 | 例子 | 开发者的动作 |
|---|---|---|---|
| system_grant | 安装即授予 | 网络联网 | 配置里声明即可 |
| user_grant | 运行时弹窗 | 相机、麦克风、定位、通讯录 | 声明 + 代码申请 + 处理拒绝 |
声明写在模块的 module.json5:
{ "module": { "requestPermissions": [ { "name": "ohos.permission.CAMERA", "reason": "$string:camera_reason", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } } ] } }
三个字段各有讲究:reason 是弹窗里给用户看的理由文案(必须经字符串资源引用,不能写死中文——这也顺手建立了多语言习惯);usedScene 声明使用场景,inuse 表示仅前台使用;abilities 挂到具体 Ability。配置敷衍(理由空泛、场景错报)在审核阶段是会被打回的典型问题,第 8 章上架前还会再过一遍。
代码侧的申请与拒绝处理:
import { abilityAccessCtrl, Permissions } from '@kit.AbilityKit'; async function ensureCamera(): Promise<boolean> { const perms: Array<Permissions> = ['ohos.permission.CAMERA']; const atm = abilityAccessCtrl.createAtManager(); try { const result = await atm.requestPermissionsFromUser(perms); return result.authResults[0] === 0; } catch { return false; } }
requestPermissionsFromUser 弹系统申请框,返回的 authResults 数组与请求顺序对应,0 表示授予。用户拒绝后的正确姿势不是反复骚扰:功能入口给"需要相机权限"的说明与跳转设置的引导;产品上提供无相机的降级路径(从相册选图)。个别权限(如通讯录读取)属于更严的 restricted 级别,还需要 ACL(访问控制列表)申请流程——在配置里补申请理由并由平台审核,用到时查对应权限的级别即可,机制与上面一致。
权限之外,网络与数据安全的三环节纪律,逐条给出做法与理由。
传输环节。默认走 HTTPS,这在前面的 ApiClient 里已体现(https 开头的基地址)。禁止明文 HTTP:配置里不开明文豁免,真需要访问旧 HTTP 服务时也应推动服务端升级而不是降低应用的安全水位。证书校验交给系统默认策略,除非明确知道自签场景的代价。
存储环节。令牌与口令不进明文存储。第 5 章的 Preferences 存设置没问题,但登录令牌这类凭据应当使用更安全的去处:优先使用系统的统一凭据管理能力或加密存储,退而求其次也要在写入前自行加密。数据库同理,RelationalStore 的 SecurityLevel 字段(第 5 章建库时填过 S1)就是数据分级落地的位置——敏感级别高的表用更高级别,级别影响系统对该库的访问控制策略。
日志环节。打日志不打敏感数据:手机号、令牌、住址不进 hilog。调试期图方便打的脱敏版本上线前全局排查;第 2 章起我们打的所有日志都遵守了这条(域名、标签、状态码,没有载荷内容)。日志是最常被忽视的泄露面,因为它不产生任何报错。
最小化原则收尾:权限清单定期审计,用不到的删;理由文案如实;申请时机放在功能被使用的那一刻而不是启动时集中轰炸——一次性弹四个权限框的应用,用户拒绝率显著更高,且体验恶劣。
背景:备忘录的"拍照贴图"入口。操作分四步:其一,配置里声明相机权限并补理由字符串;其二,入口按钮点击先调 ensureCamera,授予则拉起相机,拒绝则显示说明与"去设置"引导;其三,真机测试三条路径(允许、拒绝、拒绝且勾选不再询问);其四,把理由文案换成空泛的"需要权限",观察弹窗说服力的差异。结果与解读:三路径里最容易被忽略的是"不再询问"分支——此后弹窗不再出现,代码拿到固定拒绝,必须靠引导设置解决;文案差异则直观展示了理由字段的用户沟通价值。变式:再加定位权限做"按地点归档笔记",把两个权限的申请拆到各自功能入口,对比启动时集中申请的体验差。
⚠️ 常见坑:只在模拟器测权限流程。模拟器对部分权限的授予行为与真机不同,发布前必须在真机走完"首次申请、拒绝、设置开关"全流程。
💡 关键直觉:权限体系的本质是把"用户对自己的数据与设备的控制权"做成显式流程。写代码时站在用户视角问一句"这个弹窗我作为用户会同意吗"——答不上来的权限,多半就是不该申请的权限。
本节要点回顾:
至此应用完成了单机加联网的全部修炼。下一章进入 HarmonyOS 最具辨识度的领域:分布式软总线、跨设备流转与元服务——你的应用将第一次"跨出"这台设备。