应用身份由平台登记
每个合作应用使用平台登记的 clientId。平台将它关联到固定厂家,并启用对应服务。Android 使用 Configuration.clientId,iOS 使用 configureWithConsent:clientId:paymentScheme:。不要沿用 SDK 默认的官方应用标识。
manufacturerId 是服务端返回的业务范围,不是接入方自由传入的授权参数。修改请求头或在 UI 隐藏其他厂家都不能替代服务端校验。
平台登录与会话
宿主调用约定的平台登录、验证接口。登录请求须携带 X-App-Client: <registeredClientId>;SDK 为它自己发起的后续请求添加此请求头,宿主自行发起的请求仍由宿主负责。
登录响应原样交给 SDK,会话包含:
| 字段 | 含义 |
|---|---|
user.id |
平台用户 ID,字符串 |
accessToken |
平台签发的访问令牌 |
expiresAt、verifiedAt |
ISO 8601 时间 |
clientId |
与 SDK 配置一致的应用身份 |
manufacturerId |
平台签发的厂家范围,官方跨厂家会话可以为空 |
SDK 校验会话并安全存储。伪造 JSON 字段不会取得平台权限。合作方自有 token 不能直接作为平台 token;当前版本不提供合作方账号换票。
两种应用范围
| 场景 | 车辆 | 商城与门店 |
|---|---|---|
| 无限骑行官方 APP | 按用户授权访问不同厂家车辆 | 根据选中的 vehicleId 解析厂家 |
| 固定厂家 APP | 只能绑定和访问平台允许的对应厂家车辆 | 浏览固定厂家内容,可省略浏览接口的 vehicleId |
下单仍需明确的 vehicleId 和 bindingVersion。厂家应用传入不匹配车辆时,不能借此切换厂家。订单同时受账号与应用范围限制;金额、库存、可执行动作以服务端返回为准。
未知或停用的应用不能登录。厂家会话不能通过删掉 X-App-Client 或改成官方标识扩大权限。正式交付前由平台确认应用登记、厂家映射及对应服务已经启用。
会话变化与退出
账号或 token 改变后,取消旧云操作,等待回调,安装新会话并重新创建车辆与商城客户端。清除旧 UI 的车辆、订单和地址状态,避免异步旧结果展示到新账号下。
退出使用 SDK 的 clearSession 或 account.clear,不要直接修改安全存储。待确认绑定、解绑和支付记录由 SDK 管理;重新登录原账号时走恢复流程。
车辆缓存与云恢复记录按 API 基址、clientId 和账号隔离;token 更新不改变记录归属。终端连接凭据仍按账号/终端保存,测试和正式环境继续使用独立安装身份与存储。
从 0.2.0 及更早版本升级时,旧记录没有保存 API/clientId 来源。有未认领的待处理记录会返回 LEGACY_SCOPE_REQUIRED。宿主必须从原安装配置核实来源,在原账号、原 API 基址和 clientId 下调用 adoptLegacy(参数空对象),成功后再 recover。不要对任意当前环境自动认领,也不要删除旧记录绕过错误。LEGACY_SCOPE_CONFLICT 表示已认领到另一来源,应回到该来源处理。旧记录保留,已完成的记录不会被再次恢复。
应用标识的安全边界
clientId 可以出现在安装包内,它不是秘密,也不能证明请求来自某个真实安装包。当前版本未集成 App Attest、Play Integrity 或包签名验证。需要这些保证的合作方案应另外约定应用真实性验证,不能把公开标识当作密钥。
不要把平台管理密钥、设备凭据或支付签名参数写入前端配置、日志或埋点。支付由 SDK 调用,订单资金状态由服务端确认。
Android:安装登录响应后创建客户端
先按 Android 接入配置已登记的 clientId 并取得隐私同意。在主线程调用下面的函数,传入平台登录响应原文和约定 API 基址。setSession 同步返回;配置或会话无效时会抛出异常。宿主捕获并提示会话错误,成功前保持业务页面关闭,不记录 JSON 或异常中的凭据。
import android.content.Context
import net.oou.mobile.CloudVehicles
import net.oou.mobile.MobileSdk
fun installVehicleSession(
context: Context,
platformSessionJson: String,
apiBase: String,
language: String
): CloudVehicles {
MobileSdk.setSession(context, platformSessionJson)
return MobileSdk.vehicles(context, apiBase, language)
}
iOS:在会话写入成功后继续
完成 iOS 初始化后,在主线程调用;成功分支再创建客户端并进入恢复流程。以下 ready 和 failure 由宿主提供,失败时保持业务入口关闭。
#import <InfiniteRideMobile/InfiniteRideMobile.h>
void InstallVehicleSession(NSString *sessionJSON, NSString *apiBase,
NSString *language,
void (^ready)(IRCloudVehicles *), IRReject failure) {
[[IRMobileSDK account] write:sessionJSON resolve:^(id value) {
IRCloudVehicles *vehicles = [[IRCloudVehicles alloc]
initWithBaseURL:apiBase language:language];
ready(vehicles);
} reject:failure];
}
