
1. 先说清楚为什么不直接扫码偏要折腾API远程添加用过萤石设备的人都知道最省事的添加方式是扫码手机App打开扫一下机身二维码摄像头自动绑定到账号下。这套流程对家庭用户来说确实友好但一旦场景变成批量安装远程运维或者第三方平台集成扫码方案就完全不够用了。举个我实际遇到的场景给一家连锁门店做视频监控改造总部要求所有分店的摄像头统一汇聚到一个平台里统一查看。分店分布在好几个城市设备由当地安装工人拆箱上电但工人的手机不能也不应该绑定到总部的萤石账号下。这时候如果还靠人工扫码添加就得有人拿着总部账号一台一台去扫效率极低而且账号密码在多个手机间流转本身就是安全隐患。另一个高频需求是第三方平台集成。比如你做了一套自己的SaaS系统要给客户提供视频巡检功能客户的摄像头是萤石设备你需要让客户授权后由你的后端服务通过API把摄像头批量添加进来。这种场景下你拿到的是API接口调用权而不是萤石App的账号权限流程和扫码完全不同。这篇文章我来完整梳理一遍通过萤石开放平台API远程添加摄像头的链路从账号准备、开发者认证、应用创建到调通接口、处理设备添加结果、常见报错排查每一步都按实际操作的顺序来写并补上文档里不会写明的坑。2. 前置准备开放平台账号、开发者认证、应用创建这三件事不能乱2.1 你要区分萤石云视频App账号和开放平台账号很多第一次接触的人会误以为我注册了萤石云视频App就能直接调API。不是的。萤石的体系里App端账号和开放平台账号是两个独立入口萤石云视频App账号面向终端用户通过手机号注册用于管理自己名下的设备。萤石开放平台账号面向开发者需要单独注册登录后创建应用获取AppKey/Secret所有API调用都基于这一对密钥。官方入口是open.ys7.com进去之后用手机号注册一个开发者账号。注册完成后登录到开放平台控制台你会看到我的应用之类的菜单点进去创建应用。创建应用时需要填写应用名称、应用类型、应用描述等信息。应用类型一般选工具类或者第三方平台取决于你最终的服务形态。这里有一点要提醒应用创建后默认处于测试状态可以调用接口但设备数量、API频次有配额限制如果要做正式商用需要申请上线或者正式发布平台会审核你的应用用途。2.2 AppKey和Secret的权限边界要搞懂创建应用后你会拿到一对关键凭证AppKey和Secret。用大白话解释这两个东西AppKey相当于你的应用ID是公开的用来标识我是谁Secret相当于你的应用密码用来签名请求证明我确实是我。在萤石开放平台的API签名机制中Secret不会直接出现在请求URL里而是通过MD5加密后生成一个sign参数。具体的签名规则文档里有但很多人第一次看容易迷糊我用人话翻译一遍取出请求参数不包括signture按参数名的ASCII码升序排列。拼接成key1value1key2value2...的形式。在拼接得到的字符串末尾附加上你的Secret。对整体做MD5运算得到32位小写字符串这就是sign。举个例子假设请求参数有accessToken和deviceSerial排序后是accessTokenxxx、deviceSerialxxx拼接成accessTokenxxxdeviceSerialxxx末尾加上Secret然后MD5。所以你在代码里一定不要把Secret硬编码到前端或任何客户端里。它应该只存在于你的后端服务中。这个道理和不要把数据库密码写到前端一样属于基础安全常识但我在实际对接第三方项目时见过不止一次有人把Secret放在H5页面里做请求签名这等于把自家大门钥匙递给了别人。开放平台的AppKey和Secret泄露后对方可以直接调用你的授权接口操作你账号下的设备风险远比想象中大。2.3 获取AccessToken所有API调用的前提萤石开放平台的接口调用大部分都需要先拿到accessToken。获取方式是在开放平台控制台里创建一个Token或者通过接口动态获取。两种方式控制台手工创建Token登录开放平台在接口调试或Token管理里手工生成一个有效期一般是7天适合测试阶段。接口方式动态获取通过https://open.ys7.com/api/lapp/token/get这个接口传入appKey和appSecret换取一个accessToken有效期同样是7天。生产环境我强烈建议用接口动态获取然后把Token缓存起来快过期时自动刷新。因为手工Token一旦过期要登录控制台重新创建太麻烦而且你永远不知道它什么时候会失效导致线上服务突然报accessToken无效。获取Token的请求很简单用GET就能完成。但要注意这个接口本身也需要带签名吗答案是不需要。获取Token的接口比较特殊它是用明文appKey和appSecret换Token官方文档写得很清楚这是个例外。其他绝大多数业务接口都需要带accessToken有的还需要带sign签名。3. 远程添加摄像头的核心逻辑设备序列号验证码跟扫码是同一条路3.1 从App扫码添加看远程添加的本质要理解API远程添加先理解App扫码添加在做什么。萤石摄像头机身上有两个关键信息一个是设备序列号deviceSerial通常是一个以字母开头的字符串印在机身贴纸上也是二维码内容的一部分另一个是验证码validateCode一般是一串大写字母和数字的组合也印在贴纸上。App扫码时实际上就是解析二维码内容提取出设备序列号和验证码然后带着这两个参数去请求云平台添加设备。云平台校验设备存在、校验验证码正确后把设备绑定到当前账号下。API远程添加的逻辑完全一致只是把扫码解析参数替换成你自己提供参数。所以你需要拿到每台摄像头的设备序列号和验证码。怎么拿两条路设备机身上直接看贴纸上有但装到天花板上之后再想看不现实。出厂包装盒上也有印。如果你有自己的设备渠道管理可以在设备出库前统一登记序列号和验证码形成一张设备台账表后续API添加时批量传入。这里必须点名一个坑一个设备序列号只能被绑定一次。如果这台摄像头之前已经绑定过某个账号你需要先让原账号解绑或者做设备转移否则API添加时会报设备已添加或设备已被绑定之类的错误。我后面专门有一节讲这个。3.2 核心接口添加设备和绑定设备萤石开放平台与添加摄像头相关的核心接口我用表格列一下接口名称接口地址作用添加设备/api/lapp/device/add把设备添加到账号下设备列表/api/lapp/device/list查询账号下绑定的设备列表设备信息/api/lapp/device/info查询单个设备的详细信息删除设备/api/lapp/device/delete把设备从账号下移除设备抓图/api/lapp/device/capture主动触发设备抓图云台控制/api/lapp/device/ptz/start控制球机转动先看最核心的/api/lapp/device/add这个接口它的请求参数参数名类型必填说明accessTokenString是调用凭证deviceSerialString是设备序列号validateCodeString是设备验证码就这么简单对核心参数就这三个。accessToken指向你的账号身份deviceSerial和validateCode指向具体的设备。请求成功后会返回设备的基本信息包括设备名称、设备类型、通道数量等。需要说明的是这个接口在文档里的字段要求是固定的但如果你用了高版本接口比如新版/v2接口参数名可能略有差异以官方最新文档为准。我写这篇文章时用的是通用的/api/lapp/device/add大多数项目用这个就够了。3.3 代码示例Python版本下面我给一个Python示例包含获取Token和添加设备两个步骤。先获取Tokenimport hashlib import time import requests APP_KEY 你的appKey APP_SECRET 你的appSecret def get_access_token(): url https://open.ys7.com/api/lapp/token/get params { appKey: APP_KEY, appSecret: APP_SECRET } resp requests.get(url, paramsparams) data resp.json() if data.get(code) 200: return data[data][accessToken] else: raise Exception(f获取Token失败: {data})然后添加设备def add_device(access_token, device_serial, validate_code): url https://open.ys7.com/api/lapp/device/add params { accessToken: access_token, deviceSerial: device_serial, validateCode: validate_code } resp requests.post(url, dataparams) data resp.json() if data.get(code) 200: print(f设备 {device_serial} 添加成功) else: print(f添加失败: {data}) return data # 主流程 token get_access_token() add_device(token, E12345678, ABCDEF)这里要注意的是请求方式。不同接口对GET和POST的要求不一样device/add接口我用的是POST。如果你用了GET而接口要求POST会得到请求方式错误或者类似提示。最保险的做法是严格按照官方文档标注的请求方式来。3.4 代码示例Java版本很多做后端集成的人用的是Java我也给一个Spring环境下的实现。先写一个工具类处理签名public class Ys7ApiClient { private static final String TOKEN_URL https://open.ys7.com/api/lapp/token/get; private static final String ADD_DEVICE_URL https://open.ys7.com/api/lapp/device/add; private String appKey; private String appSecret; public Ys7ApiClient(String appKey, String appSecret) { this.appKey appKey; this.appSecret appSecret; } public String getAccessToken() { // 使用RestTemplate或OkHttp发起GET请求 // 返回accessToken } public String addDevice(String accessToken, String deviceSerial, String validateCode) { // 组装POST表单参数调用ADD_DEVICE_URL // 解析返回JSON判断code是否为200 } }核心逻辑和Python版本一样先获取Token再POST提交添加设备参数。Java里要注意的是deviceSerial和validateCode不需要额外做URL编码直接作为表单参数提交即可。4. 批量远程添加的工程化思路别用for循环硬调接口4.1 为什么批量添加不能简单循环如果你需要添加的摄像头只有三五个写一个循环逐台调用device/add接口问题不大。但一旦设备量到了几十上百台事情就变了。几个实际问题实时性要求变了。几十台设备逐台添加每台网络请求按300毫秒算100台就是30秒但中间如果遇到超时、限流、报错重试实际耗时轻松翻倍。用户在前端页面等待的体验会很差。失败处理复杂度上升。哪一台失败了失败原因是什么是验证码错误、设备不在线、还是网络波动这些信息需要被记录和归类才能指导后续处理。平台限流。开放平台对API调用频次有配额限制高频调用会被拒绝或降速。一次性打太多并发请求很容易触发调用超频之类的错误码。所以在工程层面批量添加的正确姿势是任务化、异步化、持久化。4.2 一个更合理的批量添加方案我实际采用过的方案是这样的结构不算复杂但能稳定支撑几百台设备的接入前端或运维人员把设备清单上传到后台格式为CSV或Excel包含两列设备序列号、验证码。后端把这批设备记录写入一张任务表状态为待处理。一个后台任务定时任务或消息队列消费者逐条取出待处理设备调用萤石API添加。每台设备处理完后更新任务状态成功/失败/失败原因。整体任务结束后统计成功与失败数量把失败清单导出供人工核对。这个流程有几个好处即使某台设备添加失败不会影响其他设备任务可以中断后从失败处继续所有操作都有日志可追溯。设备任务表可以这样设计CREATE TABLE device_add_task ( id BIGINT PRIMARY KEY AUTO_INCREMENT, device_serial VARCHAR(32) NOT NULL, validate_code VARCHAR(16) NOT NULL, status TINYINT NOT NULL DEFAULT 0 COMMENT 0-待处理 1-成功 2-失败, error_msg VARCHAR(255), create_time DATETIME, update_time DATETIME );然后任务调度器里每次取一批待处理记录逐条调API按照结果更新状态def process_batch(): tasks get_pending_tasks(limit10) token get_access_token() for task in tasks: try: add_device(token, task.device_serial, task.validate_code) mark_success(task.id) except Ys7ApiException as e: mark_failed(task.id, e.message)注意获取Token要尽量复用不要每添加一台设备就重新获取一次Token。**Token有效期7天正常使用完全可以做到全局复用。**频繁调用Token接口除了浪费还可能触发频控。4.3 验证码的自动化管理批量添加场景里另一个容易被忽视的问题是验证码的采集与维护。验证码是印在设备上的正常情况下只有设备机身上有。你如果只是一个两个设备看一眼输进去就行。但要批量添加几十上百台必须提前维护好设备台账把这些验证码准确录入系统。这里有个常见的现实问题工程安装过程中贴纸可能被撕掉、磨损或者被灰尘遮挡导致看不清。遇到这种情况没有取巧的办法只能通过设备自身的二维码图片来识别或者联系萤石客服/设备厂商协助查询。另外一个经验是添加成功后验证码其实就不那么重要了。设备已绑定到账号后再添加或绑定操作就不需要验证码了。所以验证码只在首次添加阶段关键。5. 处理设备添加失败完整排查链路复盘5.1 错误码是第一步线索萤石开放平台的API错误码体系是一个统一的返回结构所有接口返回的JSON都会包含code和msg字段。code为200表示成功其他都是失败。我在实际项目中遇到过的、与添加设备强相关的错误码主要有错误码含义我的处理方式10005accessToken无效或过期重新获取Token后重试20001设备不存在检查序列号是否输错20002设备已被添加先确认是否已绑定到本账号或其他账号20004验证码错误核对机身验证码20010设备已被其他账号绑定需要原账号解绑或走设备转移20012设备不在线确认设备是否通电并联网40002接口调用频次超限降低调用频率或申请提高配额注意看这两条的区别20002强调的是设备在当前体系里已经被绑定可能是你这个账号也可能是别的账号提示语一般是设备已被添加。20010更明确地告诉你被其他账号绑定了。两者出现时都不太可能通过换个Token重试解决必须先处理绑定关系。5.2 一个真实排查案例设备显示已添加但查不到有次给一家公司做项目对接对方反馈通过API添加设备返回20002 设备已被添加。但我用同一个appKey对应的账号去查询设备列表却查不到这台设备。这就很迷惑了。设备在云端已经被标记为已添加但当前账号下又看不到。仔细排查下来原因是这样这台设备的序列号确实存在但它被绑定在了另一个账号下——很可能是设备出厂时由经销商或上一任集成商的账号预先批量添加过。因为API查询设备列表只查当前accessToken对应账号下的设备所以我这边当然是看不到但云端判定已被添加。解决办法有两个方向找到原绑定账号登录后在设备管理里删除该设备让设备回归未绑定状态。通过萤石官方的设备转移流程把设备从原账号转移到当前账号。设备转移往往比简单删除更复杂因为涉及所有权变更有的需要原账号的权限确认。如果你没有原账号的权限那就只能联系设备厂商或萤石售后走人工流程。这一块不要试图通过API绕过——从平台设计上讲绕过设备所有权归属校验意味着严重的安全漏洞平台不会留这种后门。5.3 accessToken过期比想象的更隐蔽10005 accessToken无效或过期这个错误很多人遇到时第一反应是Token是不是被重置了。我遇到过一种隐蔽的情况Token明明没到7天有效期突然就10005了。后来查明是开放平台的安全策略升级后某些高风险操作比如频繁更换IP、短时间内大量调用敏感接口会触发Token失效保护让Token提前作废。这种情况没有特别好的预报手段能做的就是全局捕获10005错误码捕获后重新获取Token并自动重试。你要在代码里把这个逻辑做成自动容错不要每次都要人工干预。我一般会在API客户端封装里加这样一段逻辑def api_call_with_retry(func, *args, **kwargs): token get_cached_token() result func(token, *args, **kwargs) if result.get(code) 10005: refresh_cached_token() token get_cached_token() result func(token, *args, **kwargs) return result这样一来即使Token意外失效也能在下次请求时自动恢复不会中断业务。5.4 设备不在线添加成功不代表能看画面再补充一个容易混淆的点。device/add成功返回200只代表设备已成功绑定到账号不代表设备现在能出画面。摄像头能不能出画面取决于设备当前是否在线、网络是否通畅、通道是否正常。我在实战里遇到过一种情况设备添加成功但视频预览一直黑屏或提示设备不在线。排查后发现是设备所在网络的DNS解析有问题导致设备无法连接到萤石云服务器所以设备状态始终是离线。这种情况下API层面的添加操作是无能为力的。你需要做的是检查设备的网络环境或者引导现场人员重启设备、检查路由器设置。API能做的是通过/api/lapp/device/list和/api/lapp/device/info周期性检查设备在线状态一旦发现设备上线再去做后续的抓图、录像、直播拉流等操作。这里分享一个我在项目里的做法设备添加成功后会进入一个等待上线的状态后台每2分钟轮询一次设备信息接口直到设备状态变为在线才向前端返回添加完成。这样做的好处是用户看到的不是添加成功但黑屏的困惑状态而是更有意义的设备在线可正常预览。6. 设备添加之后的常用关联操作拿流地址、抓图、云台控制6.1 获取视频直播地址设备添加完成后最常见的需求就是看视频。在萤石开放平台上看视频的路线一般是通过获取HLS直播地址或RTMP推流地址然后在自己的播放器里播放。获取直播地址的接口是/api/lapp/live/address/get核心参数是设备序列号和通道号channelNo。对于单通道摄像头通道号一般为1。请求示例def get_live_address(access_token, device_serial, channel_no1): url https://open.ys7.com/api/lapp/live/address/get params { accessToken: access_token, deviceSerial: device_serial, channelNo: channel_no } resp requests.post(url, dataparams) data resp.json() if data.get(code) 200: return data[data] else: raise Exception(f获取直播地址失败: {data})返回的数据里通常包含多个清晰度对应的地址高清、标清、流畅你在实际使用时可以根据业务场景选择。要注意这些直播地址本身有一个有效期需要在有效期内使用。如果你的业务需要长期稳定的播放建议设计一个定时刷新地址的机制。流地址过期这个坑我印象很深。第一次做集成的时候我把直播地址直接存到数据库里想着反正是一段URL第二天用户反馈看不了视频排查发现URL已经失效了。后来改成前端需要播放时实时向后端要地址后端带缓存地调API获取问题彻底解决。6.2 设备抓图另一个高频操作是抓图。比如在安防场景中有人触发报警后系统需要抓取当前画面留证。抓图接口是/api/lapp/device/capture。同样需要传入accessToken、deviceSerial、channelNo三个参数。抓图成功后设备会生成一张JPEG图片通过回调或主动查询的方式拿到图片地址。这个接口有一件事需要提前知道抓图是一个异步过程。接口返回200只代表指令已下发或者抓图成功取决于具体设备固件和接口版本。有的设备需要几秒到十几秒才能完成抓图并生成图片。所以你在业务逻辑里不要拿到200就立刻去下载图片需要做适当的延迟或重试。6.3 云台控制如果你的摄像头是球机云台式可以调用云台控制接口让它转动。控制接口是/api/lapp/device/ptz/start常用方向有上、下、左、右、左上、左下、右上、右下以及变倍操作ZOOM_IN、ZOOM_OUT。云台控制的请求参数多一个action取值是start和stop。为什么要有start和stop因为云台转动不是一个转一下到指定位置的动作而是按住才转、松开就停的持续动作。这和遥控器控制电动窗帘逻辑类似按下开始转松开停止转。所以前端交互上一般是在鼠标按下时调用start松开时调用stop。如果只调start忘记调stop设备会一直转到行程尽头才停电机容易磨损。这种低级但常见的错误我至少见过两次。7. 设备在不同账号间转移、解绑以及所有权边界7.1 设备转移不是你想象的那样设备转移是另一个常被提上日程的需求。典型场景我作为集成商用我的开发账号把设备都添加进来了调试完成后需要把设备移交到客户的账号下。怎么通过API转移先说结论萤石开放平台的API不支持直接跨账号转移设备所有权。这个操作在API层面做不了。能做的方案是什么用原账号调删除设备接口把设备解绑。目标账号重新添加设备前提是设备处于未绑定状态且你有设备验证码。这个流程本质上就是先解绑、再重新添加中间会有一段设备无归属的空窗期。如果你的业务场景对连续性有要求就要规划好操作窗口。这里牵扯到另一个话题设备所有权和绑定权的关系。在很多IoT平台上设备所有权属于第一个绑定它的账号只有所有权账号能删除或转移设备其他账号只能查看或共享。萤石体系里删除设备这一操作有严格权限校验跨账号删除一般来说是不可能也不被允许的。我没有必要在公开文章里探讨绕过方法这类绕过如果可行对整个平台生态是灾难性的。7.2 设备被误删了怎么办比起转移更常见的是不小心解绑。比如测试环境里调了删除接口把一台真实设备从测试账号下解绑了过两天想加回来发现验证码不记得了。怎么办如果设备二维码还在扫一下就行如果贴纸丢了、设备在高处够不到那就麻烦了。所以我的强烈建议是维护好设备台账把序列号和验证码提前录入系统做好备份而不是依赖机身贴纸或二维码。我在项目初始就会做一张完整的设备信息表字段包括设备名称设备序列号验证码安装位置所属门店/客户添加时间绑定账号备注这张表在后续需要重新添加、故障排查、对账时都会派上大用场。8. 安全与合规经验API Key权限、Token存储与最小化授权8.1 权限最小化原则在实际对接中我始终坚持一条原则每个第三方系统单独创建应用而不是共用一个应用。假设你给两个不同客户做视频平台集成这两个客户都用你的AppKey去添加设备。用同一个AppKey意味着两个客户的所有设备都混在同一个开放平台账号下权限边界完全模糊。某个客户想删除自己的设备API层面根本做不了这种只删自己的限制因为设备在这个账号下并没有属于哪个客户的概念。正确的做法是每个客户创建各自的应用拥有独立的AppKey和Secret设备各自绑定到各自的应用账号下。这样权限天然隔离即便某一边的密钥泄露影响面也控制在单个客户范围内。具体来说在开放平台控制台你可以创建多个应用。每个应用有独立的AppKey和Secret设备绑定互不干扰。8.2 Secret泄露的应急响应如果真的发生Secret泄露别慌按这个顺序处理登录开放平台控制台重置Secret让旧Secret立即失效。同时重置或删除所有accessToken因为Token是基于旧Secret生成的新Secret生效后旧Token大概率也会作废。检查设备列表看有没有被非授权方添加的设备。检查api调用记录如果有的话判断是否有异常访问。我之前参与过一个项目对接方把Secret写在了Git仓库里后来仓库被公开机器人很快就扫到了Secret并开始批量调用接口。最终靠重置Secret才止损。所以Git仓库加.gitignore忽略配置文件、密钥通过环境变量或密钥管理系统注入这些看似基础的规范关键时刻能救命。8.3 数字化密钥管理的补充如果你的团队已经有成熟的密钥管理系统比如Vault、KMS当然更理想。不过现实是很多中小项目连环境变量都没用明白这方面我觉得不用追求过度复杂先做到Secret不进代码、不进仓库、不落前端然后根据项目规模决定要不要上专业密钥管理系统。9. 实战中容易踩的小坑与经验补遗9.1 请求参数的编码问题调用device/add接口时deviceSerial和validateCode都是英文字母和数字的组合一般不涉及编码问题。但如果你在业务系统中传递的参数包含中文比如设备名称、备注在拼接POST表单或URL时要注意编码一致。具体来说统一使用UTF-8编码。有个朋友遇到过一种诡异现象同样的参数同一台设备周一添加成功周五添加失败提示验证码错误。排查了半天发现是他在代码里改了全局字符编码配置导致POST请求正文从UTF-8变成了GBK中文参数虽然没用到倒是没事但签名验签环节把签名算错了看起来就像验证码错误。9.2 时区问题你统计设备在线、离线的日志或者计算Token过期时间时务必注意时区。萤石开放平台的错误码和返回信息里的时间字段一般用的是北京时间东八区。如果你的服务器部署在海外或者使用UTC时区直接拿服务器本地时间去做是否过期的判断可能会出现偏差。我在一个跨境项目里就踩过这个坑服务器部署在新加坡UTC8但实际配置有误导致显示UTCToken明明还有几天才到期却被本地逻辑判断为已过期。排查了很久最后发现是记录过期时间时用了UTC而判断时用了本地时间。9.3 设备通道与多目摄像头现在很多萤石摄像头是双目的、鱼眼的通道号就不是1了。添加设备成功后获取到的设备信息里会有channelNum字段表示通道数量。你在拉流、抓图时需要根据实际通道号来传参。我有一个踩过的坑一台双目摄像头通道号是1和2我在业务代码里只写了通道1的逻辑导致第二个通道的视频始终取不到。后来我在设备信息返回后根据channelNum动态创建通道列表问题才解决。9.4 接口调试工具在正式写代码之前建议先使用开放平台自带的接口调试页面把每个接口跑通。这样做的好处有两点可以直观地看到接口的入参有哪些、返回数据结构是什么。可以减少代码写了半天结果接口参数理解错了的返工时间。调试通过后再动手写生产代码心里有底得多。不要一上来就写代码、对着报错猜效率很低。10. 结尾根据我的经验再给你三句实在话第一句API远程添加摄像头真正的难点不在接口调用本身而在于你对这套体系的整体契约理解到位。设备序列号、验证码、AccessToken、应用密钥这些东西之间的关系比写几行请求代码重要得多。很多人接口调不通不是因为代码写错而是因为设备已被绑定、Token过期、或者签名算错这些外围问题。第二句把设备台账和错误码处理做成标准化能帮你省掉大量运维时间。不管是三台设备还是三百台设备我建议你都用任务化持久化自动重试的思路来处理添加流程而不是记在小本本上手动添加。也不要低估错误码自动归类的重要性它决定了你收到线上告警时是立刻能定位问题还是要花几小时去看日志。第三句安全永远要放在最前面。密钥不要出现在前端、不要提交到仓库、每个客户独立应用。这个原则在项目初期看起来是多此一举但真出了安全问题你才会意识到它有多值钱。如果你正在做萤石开放平台的设备接入希望这篇内容能帮你少走弯路。有任何接口对接上的细节问题欢迎在评论区交流我看到了会尽量回复。