数据和安全
几乎每一位使用云服务的开发者都会问,如何能够保证自己应用数据的安全?对安全的关注说明你也是位对产品负责、对用户负责、对自己负责、做事态度认真的开发者,这也正是我们所信守的价值观。
云服务所有的 API 请求都通过 SSL 加密传输,保证传输过程中的数据安全性和可靠性。 云端对客户端发过来的每一个请求,都进行了身份鉴别(Authentication)和访问授权(Authorization)的严格检查。
身份鉴别(Authentication)
访问云服务 API 需要提供应用的 AppID 和 AppKey(用于在客户端发起请求),或是 AppID 和 MasterKey(用于在云引擎、开发者自己的服务器等受信任的环境发起请求)。 Android SDK 还额外支持仅使用 AppID 访问云服务 API.
使用 MasterKey 访问云服务 API 会跳过所有的访问权限控制,所以请确保 MasterKey 不会泄露。
在客户端使用 AppKey 访问云服务 API 时:
- 客户端访问 API 通过 HTTPS 加密通讯。
- 通过 SDK 访问 API 时,HTTP Header 中不直接传输 AppKey,而是传输客户端根据 AppKey 和请求发起时间生成的签名字符串,供云端校验。开发者不通过 SDK,直接请求 REST API 时,也可以使用这种更安全的鉴权方式。
通过 HTTPS 加密通讯,不仅保护了数据安全,而且能避免 AppKey 被第三方窃取,但无法阻止别有用心的人通过在客户端使用抓包工具获取 AppKey。 通过签名字符串可以避免在网络传输过程中泄露 AppKey,但是无法阻止别有用心的人通过反编译等手段获取代码中初始化 SDK 时设定的 AppKey。 Android SDK 提供仅使用 AppID 的初始化方式,SDK 通过闭源的 native library 根据开发者配置的应用签名证书自动对请求进行签名。 这在一定程度上避免了暴露应用核心配置信息,也显著增加了破解的难度(反编译 native library 后仍需破解加密算法),但仍无法保证绝对的数据安全。 因此,凡是需要在客户端访问的应用,都需要设定 ACL 等权限设置,以保障应用数据的安全性。
访问授权(Authorization)
云服务支持在 Class(表)、字段(列)、对象三个不同的层次设置访问权限。
Class 权限
Class 权限指整个 Class(整张表)的读写权限,需要在控制台进行设置。
在创建 Class 对话框可以设置 Class 的访问权限:
add_fields
- 给 Class 增加新的字段,也就是说,保存对象时,如果对应的字段(列)不存在,是否允许自动创建新的字段。如果已经在控制台创建好 Class 的所有字段,最好对任意用户都关闭此权限,防止脏数据写入。create
- 在 Class 表中插入一个新对象。对于需要登录用户或者拥有指定授权的用户才能创建内容的场景,可以考虑根据情况设置此权限。delete
- 删除既有对象。update
- 修改既有对象。find
- 通过指定条件查询对象。关闭此权限时,无法查询对象,只能通过 objectId 获取对象(如果没有同时关闭get
权限),一定程度上可以防范别有用心的人批量抓取该 Class 下的所有对象。get
- 通过 objectId 获取单个对象。
对于每一种权限,又可以开放给不同用户:
- 所有用户 - 相当于 public 权限。这里的「用户」泛指「客户端」,而不是云服务内建账户系统的用户。也就是说,无论请求是否携带 sessionToken,携带的 sessionToken 是否有效,都可以进行这一操作。
- 登录用户 - 只有使用云服务内建账户系统(
_User
表)并且进行了登录的客户端(携带了有效 sessionToken 的请求),才可以执行这一操作。 - 指定用户 - 指定用户才可以执行这一操作。支持通过用户名、用户的 objectId、角色名、角色的 objectId 指定用户。如果留空,那么意味着所有用户都没有权限。
譬如我们有一个匿名发帖的应用,所有人都可以发表帖子,但是只有经过管理员审核后的帖子才能被展示出来。我们可以有两张表,第一张表用来存放审核前的帖子,这张表的 create 权限就可以开放给所有用户;第二张表用来存放审核后的帖子,这张表的 create 权限就只开放给管理员。
另外,你也可以修改现有 Class 的访问权限。 进入云服务控制台 > 数据存储 > 结构化数据,选择一个 Class,再点击权限标签页。
字段权限
在控制台还可以设置每个字段的权限。 访问 云服务控制台 > 数据存储 > 结构化数据,选择一个 Class,点击相应字段的下拉菜单,选择 编辑:
- 勾选 只读 后,客户端无法更新这一字段。
- 勾选 客户端不可见 后,客户端发起查询或获取对象的时候,返回的结果将不包含这一字段。比如,对于一个匿名发帖的应用,你仍然希望发帖的时候记录下真实的作者,但不希望将此信息返回给客户端。
对象权限
每个对象都有一个特殊的 ACL(Access Control List)属性。 ACL 允许开发者设定某个具体对象的权限,是最精细的权限控制方式。
比如:
- 对于私有数据,read 和 write 都可以限制为对象创建者所有(其读写权限都设置成创建者自身,并且不开放「所有用户」的读、写权限)。
- 一个信息公告板的帖子,作者和属于「版主」角色的成员可拥有修改权限,普通访客则只允许浏览(给「所有用户」开放「读」权限,给「作者」和「版主角色」开放「写」权限)。
- 应用内全局的每日头条,对所有用户是只读的,只有管理员可以修改它(给「所有用户」开放「读」权限,给「管理员角色」开放「写」权限)。
- 用户共享一篇文章给另一个用户,可以将读和写的访问许可限制到关联的这两个用户,其他人一概不可读写(对「所有用户」关闭「读、写」权限,只对两个用户开放权限)。
详细信息请参考ACL 权限管理指南。
安全设置
云服务控制台 > 设置 > 安全中心 可以设置或查看服务开关。服务开关可以用来开启或者关闭当前应用所使用的服务,从根本上防止由于 AppID 和 AppKey 泄露而可能会引发的服务资源被盗取的问题。
另外,有些子服务的开关在具体服务的设置页面,比如:
云服务控制台 > 数据存储 > 服务设置 > 安全设置 中可以设置是否开启 LiveQuery。
出于安全考虑,有些应用只在服务端调用接口向用户推送通知。对于这些应用,可以访问 云服务控制台 > 推送 > 设置 勾选 禁止从客户端进行消息推送。勾选后客户端无法推送消息,只能通过 MasterKey 调用 REST API 发送或在控制台发送(云服务控制台 > 推送 > 在线发送)。
同理,有些应用只在服务端调用接口向用户发送短信。对于这些应用,可以访问 云服务控制台 > 短信 > 设置,不勾选 启用通用的短信验证码服务(开放 requestSmsCode 和 verifySmsCode 接口)。这种情况下,应用仍然能在服务端通过 MasterKey 调用 requestSmsCode
发送短信。另外,与用户相关的短信接口与此选项无关。不勾选的情况下,客户端仍能调用用户相关的短信接口。
云服务控制台 > 数据存储 > 服务设置 > 安全设置 下可以设置 禁止客户端创建 Class。有些应用的开发者习惯预先规划好应用需要用到的 Class(表),并事先在控制台创建相应的 Class。对于这些开发者,推荐始终勾选这一选项。有些应用的开发者习惯直接着手开发应用的原型,在开发过程中逐渐完善数据结构。对于这些开发者,我们推荐在开发测试阶段不勾选这一选项,在应用上线前勾选这一选项。
云服务控制台 > 数据存储 > 服务设置 > 查询设置 下可以设置 查询 include 引入的 Pointer 类型数据时校验 ACL 权限。我们建议所有应用都勾选这一选项(这一选项默认处于勾选状态),以保证数据安全。
云服务控制台 > 内建账户 > 设置 页面下有一些用户相关的安全选项,可以要求修改密码时提供旧密码,密码修改后强制重新登录,验证第三方登录的 Access Token
是否有效。
云服务控制台 > 数据存储 > 文件 > 设置 可以限制用户上传的文件类型。
Web 安全域名
「Web 安全域名」可以限制请求来源,防止其他人通过外网其他地址盗用你的服务器资源。
「Web 安全域名」域名配置策略与浏览器域安全策略一致,要求域名协议、域和端口号都严格一致,不支持子域和通配符。所以如果你要配置一个域名,要写清楚协议、域和端口,缺少一个都可能导致访问被禁止(在使用默认端口的情况下,也可以省略端口号,比如 https://example.com
和 https://example.com:443
是等效的)。
云函数不受 Web 安全域名限制。另外,为方便开发调试,localhost 总是会被放行。
但是要注意,Web 安全域名所能达到的目的是防御恶意部署,而不是防御伪造脏数据(恶意用户通过绑定 host 的方式还是有可能访问到应用的数据),所以要想对数据进行更多细粒度的控制,需要配合 ACL 来使用。
操作日志
云服务控制台 > 设置 > 操作日志 会显示应用创建者及所有协作者的重要操作记录,比如删除数据操作的历史、操作用户名、操作 IP 及操作时间等,这个日志的目的是为了遇到问题更好地定位故障缘由,排查可能的恶意操作,防止应用数据被错误地改动。
自动备份
应用每日自动备份,云服务会保留最近 7 天的备份。商用版应用可以在 云服务控制台 > 数据存储 > 导入导出 > 备份恢复 恢复最近 7 天的数据(还可以指定需要恢复的 Class 或 objectId)。所有应用都可以在 云服务控制台 > 数据存储 > 导入导出 > 备份导出 下载备份(可以指定需要下载的备份日期、Class)。
注意:
- 开发版不支持数据恢复。
- 已删除的文件无法恢复。
- 恢复操作只会插入数据,如果有被变更过的数据需要恢复,请先把目标数据自行备份并删除后再提交任务。
- 如需恢复删除的 Class,需要在控制台手动创建一个同名的空 Class,并手动添加相应列。
此外,开发者还可以使用 数据导出功能 将应用数据备份到本地,该功能商用版、开发版均可用。