小程序权限授权机制是怎样的?如何做好安全处理?
简化版
小程序权限通常在调用敏感能力时触发授权,比如位置、相机、相册等。开发时要遵循最小权限原则,只在用户明确需要时申请,并处理拒绝授权、重新授权和降级方案。安全上不能信任前端数据,关键校验必须放在服务端。
详细版
小程序权限不是应用启动时一次性全要,而是在具体场景调用 API 时触发。比如用户点击“获取当前位置”后,再申请位置权限。
常见处理:
- 调用前说明为什么需要权限。
- 用户拒绝后给出替代方案。
- 必要时引导用户打开设置页重新授权。
- 不在无关场景强行弹授权。
安全方面,小程序前端代码运行在客户端,不能作为可信边界。用户身份、支付金额、订单归属、接口权限都必须由服务端校验。
完整版教学
一、权限授权的基本原则
小程序权限设计强调用户感知。只有当用户触发某个功能时,才应该申请对应权限。
例如进入首页就申请位置权限,用户可能不知道原因,拒绝率会很高。更好的方式是在点击“附近门店”时说明用途,再触发授权。
这叫最小权限原则:只申请当前功能必须的权限,只在必要时申请。
二、用户拒绝后怎么办
用户拒绝授权是正常路径,不是异常路径。代码必须处理。
常见降级策略:
- 位置权限被拒绝时,让用户手动选择城市。
- 相机权限被拒绝时,允许从相册上传。
- 通知权限被拒绝时,只在页面内展示提醒。
如果功能强依赖权限,可以提示用户前往设置页开启,但文案要说明原因,而不是只告诉用户“请授权”。
三、安全边界在哪里
小程序前端不能被完全信任。用户可以篡改请求参数、重放请求、伪造某些状态。
所以关键规则必须放在服务端:
- 用户是否登录。
- 用户是否有权限访问资源。
- 订单金额是否正确。
- 优惠券是否可用。
- 支付结果是否真实。
- 敏感数据是否属于当前用户。
前端可以做体验层校验,但不能代替服务端安全校验。
四、面试追问与工程落地
面试官可能问:“获取手机号、支付这类能力怎么保证安全?”
获取手机号时,前端只负责拿到平台返回的凭证或加密数据,后端负责解密、绑定和校验。支付时,订单金额必须以后端生成为准,前端不能直接决定支付金额。
工程中还应统一封装权限请求,把授权说明、失败提示、设置页引导和降级逻辑放在一起,避免每个页面重复实现。
五、四类“授权”不能混为一谈
小程序里的授权并非只有 wx.authorize 一种。位置等部分能力使用 scope 授权,摄像头等还可能受操作系统权限控制,手机号、头像昵称等能力强调用户主动操作,业务接口本身还要做服务端身份与资源授权;四层解决的问题不同。
| 层次 | 典型问题 | 处理方式 |
|---|---|---|
| 隐私与用途告知 | 为什么收集、如何使用 | 按平台规则提供隐私说明并取得必要同意 |
| 小程序 scope | 某项平台能力是否授权 | 调用能力、检查设置、拒绝后提供引导 |
| 操作系统权限 | 微信是否有相机/定位权限 | 提示用户到系统设置处理 |
| 业务授权 | 当前用户能否操作订单 | 服务端认证、权限与资源归属校验 |
不是所有敏感能力都能靠 wx.getSetting 得到一个永久开关,也不能在任意时机自动弹出。获取手机号、订阅消息等有各自的用户手势、次数或接口规则,封装权限层时要按能力分类,而不是把所有 API 套进同一个“先 authorize”函数。
六、服务端校验与重放防护
前端展示金额 99 元,攻击者可以把请求改成 0.01 元,所以后端必须根据商品 id、数量、活动和账户权益重新计算金额。创建订单与支付回调还要有不可预测的订单号、幂等状态机,并验证平台回调签名与金额;“客户端显示支付成功”不是服务端入账依据。
客户端提交意图 → 服务端认证身份
→ 校验资源归属/业务规则
→ 生成权威金额与订单
→ 平台支付
→ 服务端验签回调并幂等更新
接口应执行最小权限:普通用户 token 不能调用管理接口,A 用户不能靠替换 orderId 读取 B 的订单。对验证码、优惠券、支付等高价值操作设置频率限制和幂等键;若网络重试 3 次,后端应返回同一操作结果,而不是创建 3 笔订单。
日志记录用户、接口、资源、结果和 request id 以便审计,但要脱敏手机号、token、session_key 与支付数据。前端代码和请求都可被观察,任何放进包内的 AppSecret、私钥或“隐藏接口口令”都应视为已泄露。
安全边界:前端负责解释和体验,服务端负责身份、权限、金额与最终状态;用户同意授权不等于获得业务资源权限。
七、常见误区与追问
- 误区:用户允许位置权限后,服务端就可以信任客户端上传的坐标。 授权只允许设备提供数据,客户端请求仍可篡改,高风险业务需要额外风控与校验。
- 误区:调用
wx.getSetting能覆盖所有敏感能力的授权状态。 不同能力可能依赖 scope、用户手势、订阅授权或系统权限,必须按对应文档处理。 - 误区:把按钮禁用就能阻止越权操作。 前端限制可以被绕过,服务端必须独立检查角色、租户和资源归属。
- 追问:用户拒绝权限后能否反复自动弹窗? 应进入明确降级流程,必要时由用户主动打开设置,不能用连续打扰逼迫授权。
- 追问:支付结果为什么不能以前端回调为准? 客户端环境不可信且可能断网或伪造,后端应验签平台通知并主动查询兜底。
- 追问:如何防止接口重放? 使用短期凭证、随机挑战或幂等键、时间窗口与服务端状态机,具体强度按业务风险设计。
- 追问:统一权限封装应该返回什么? 返回已授权、已拒绝、系统受限、需用户操作等可区分状态,让页面选择降级而不是统一报错。
八、加强记忆
权限题先拆四层:隐私用途说明、小程序能力授权、操作系统权限、服务端业务授权,不能用一个 scope 概念包办。申请时遵循场景触发和最小权限,拒绝是正常分支并要有降级;安全上始终把客户端当作可篡改环境,身份、资源归属、金额、支付回调和幂等状态全部在后端闭环。