更新记录

1.0.0(2026-10-12)

初始版本


平台兼容性

uni-app(5.31)

Vue2 Vue2插件版本 Vue3 Vue3插件版本 Chrome Safari app-vue app-vue插件版本 app-nvue app-nvue插件版本 Android Android插件版本 iOS 鸿蒙
√ 1.0.0 √ 1.0.0 × × √ 1.0.0 √ 1.0.0 4.4 1.0.0 × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

atrust-sdk(深信服 aTrust 零信任 SDK)UTS 插件

基于 SangforSDK.aar(SDK 2.2.12.1,类入口 com.sangfor.sdk.SFUemSDK)封装,仅支持 App-Android(arm64-v8a / armeabi-v7a,不支持 x86 模拟器)。

目录约定

utssdk/
  interface.uts            对外类型与 API 声明
  app-android/
    index.uts              Android 实现(Kotlin 编译)
    config.json            minSdkVersion 21 + abi 配置
    AndroidManifest.xml    SdpVpnService / VpnPermissionActivity / usesCleartextTraffic
    libs/SangforSDK.aar    官方 SDK

环境要求

项 要求
平台 App-Android(真机或 ARM 模拟器)
ABI armeabi-v7a、arm64-v8a
minSdkVersion 21
SDK 版本 SangforSDK 2.2.12.1
不支持 x86 / x86_64 模拟器

注意:HBuilderX 运行到标准模拟器(通常为 x86)会直接崩溃,请使用 ARM 真机 或制作 ARM 自定义调试基座。

初始化

在应用入口(如 App.uvue 的 onLaunch)调用一次即可,幂等:

import { initSDK } from '@/uni_modules/atrust-sdk'

// mode: 'mutable' | 'sandbox' | 'vpn_sandbox',默认 'mutable'
initSDK('mutable')
  • mutable — 动态权限模式(官方推荐),认证后由服务端策略动态决定 VPN/沙箱。
  • sandbox — 纯沙箱模式,全部流量走沙箱 TCP 代理。
  • vpn_sandbox — VPN + 沙箱混合模式。

API 一览

认证相关

函数 说明
startAutoTicket() 自动免密认证,返回 boolean;true 表示已认证可直接访问资源
startPasswordAuth(serverUrl, username, password) 用户名密码主认证,返回 Promise<ATrustAuthResult>
startPrimarySmsAuth(serverUrl, phone) 短信验证码主认证(无需密码),返回 Promise<ATrustAuthResult>
doSecondaryAuth(authType, code, username, password, authId) 二次认证提交,返回 boolean
doRenewPasswordAuth(oldPassword, newPassword) 密码到期重置,返回 boolean
cancelAuth() 取消当前认证流程
logout() 注销登录

状态查询

函数 说明
getAuthStatus() 获取认证状态码(number)
getAuthStatusName() 获取认证状态名(如 AuthStatusAuthOk)
isAuthOK() 是否已认证通过(boolean)
getSdkVersion() 获取 SDK 版本号

辅助操作

函数 说明
regetSmsCode(authId?) 重新获取短信验证码,返回 Promise<ATrustSmsInfo>
regetRandCode() 重新获取图形验证码,返回 Promise<string>(base64 PNG)

隧道控制(可选)

重要:当前部署(sdkMode='mutable')下,aTrust 认证成功(onAuthSuccess / 免密成功)即可访问内网地址,认证回调后直接跳转业务页即可。不要在页面显式 registerTunnelListener() + startTunnel() 等待隧道 ONLINE 再跳转——实测该流程会卡住跳转。

函数 说明
startTunnel() 启动 VPN 隧道
stopTunnel() 停止 VPN 隧道
getTunnelStatusName() 获取隧道状态名(INIT / ONLINE / OFFLINE)
registerTunnelListener() 注册隧道状态监听
unregisterTunnelListener() 注销隧道状态监听

事件系统(uni.$on / uni.$off)

UTS 插件只能跨端导出函数,无法导出常量/字符串,因此事件名字符串定义在项目侧配置文件(config/atrust.config.ts 的 ATRUST_EVENTS),页面使用时务必从项目配置导入,不要硬编码。

事件 payload 类型 触发时机
ATRUST_EVENTS.AUTH_SUCCESS string(JSON 序列化的 ATrustAuthResult) 认证成功
ATRUST_EVENTS.AUTH_FAILED string(JSON 序列化的 ATrustAuthResult) 认证失败
ATRUST_EVENTS.AUTH_PROGRESS string(JSON 序列化的 ATrustProgress) 需要二次认证
ATRUST_EVENTS.LOGOUT string(JSON 序列化的 ATrustLogoutInfo) 被服务端注销/踢下线
ATRUST_EVENTS.TUNNEL_STATUS string(JSON 序列化的 ATrustTunnelStatusInfo) 隧道状态变化

使用示例

import { ATRUST_EVENTS } from '@/config/atrust.config'
import { ATrustAuthResult, ATrustProgress } from '@/uni_modules/atrust-sdk'

onLoad(() => {
  uni.$on(ATRUST_EVENTS.AUTH_SUCCESS, (payload: string) => {
    const res = JSON.parse<ATrustAuthResult>(payload)
    console.log('登录成功', res.serverInfo)
  })

  uni.$on(ATRUST_EVENTS.AUTH_PROGRESS, (payload: string) => {
    const p = JSON.parse<ATrustProgress>(payload)
    if (p.authType === 'AUTH_TYPE_SMS') {
      console.log('短信验证码已发送,倒计时', p.countDown)
    }
  })

  uni.$on(ATRUST_EVENTS.AUTH_FAILED, (payload: string) => {
    const res = JSON.parse<ATrustAuthResult>(payload)
    console.log('登录失败', res.errStr)
  })
})

onUnload(() => {
  uni.$off(ATRUST_EVENTS.AUTH_SUCCESS)
  uni.$off(ATRUST_EVENTS.AUTH_PROGRESS)
  uni.$off(ATRUST_EVENTS.AUTH_FAILED)
})

类型定义

ATrustAuthResult

type ATrustAuthResult = {
  errCode: number      // SDK 错误码,0 表示成功
  errStr: string       // 结果描述
  authType: string     // 当前认证类型(SFAuthType 枚举名)
  serverInfo: string   // 第三方服务器返回信息(通常含 SSO 票据/用户信息)
}

ATrustProgress

type ATrustProgress = {
  authType: string           // 下一步认证类型
  errStr: string             // 服务端提示信息
  phoneNum: string           // 短信认证:手机号
  countDown: number          // 短信认证:倒计时(秒)
  stillValid: boolean        // 短信认证:上次验证码是否仍有效
  randImageBase64: string    // 图形码认证:图片 base64(PNG)
  services: ATrustServiceInfo[] // 多选一服务列表,>1 时需先选择
}

ATrustServiceInfo

type ATrustServiceInfo = {
  authId: string
  authName: string
  authType: string     // SFAuthType 枚举名
  description: string
}

ATrustSmsInfo

type ATrustSmsInfo = {
  phoneNum: string
  countDown: number
  stillValid: boolean
}

ATrustLogoutInfo

type ATrustLogoutInfo = {
  logoutType: string   // SFLogoutType 枚举名
  errStr: string
}

ATrustTunnelStatusInfo

type ATrustTunnelStatusInfo = {
  status: string       // SFTunnelStatus 枚举名:INIT / ONLINE / OFFLINE
  errCode: number
  errStr: string
}

完整使用示例

import { initSDK, startAutoTicket, startPasswordAuth, doSecondaryAuth, logout, regetRandCode } from '@/uni_modules/atrust-sdk'
import { ATRUST_EVENTS } from '@/config/atrust.config'
import { ATrustAuthResult, ATrustProgress } from '@/uni_modules/atrust-sdk'

// 1. 初始化(App.uvue onLaunch)
initSDK('mutable')

// 2. 尝试免密登录
if (startAutoTicket()) {
  console.log('免密成功,直接跳转业务页')
  uni.redirectTo({ url: '/pages/biz/webview' })
  return
}

// 3. 密码登录
startPasswordAuth('https://vpn.example.com', 'user@domain', 'password')
  .then((res) => { console.log('主认证成功', res) })
  .catch((err) => { console.log('主认证失败', err.errStr) })

// 4. 监听二次认证
uni.$on(ATRUST_EVENTS.AUTH_PROGRESS, (payload: string) => {
  const p = JSON.parse<ATrustProgress>(payload)

  // 短信验证码
  if (p.authType === 'AUTH_TYPE_SMS') {
    // 用户输入 code 后提交
    doSecondaryAuth('AUTH_TYPE_SMS', code, '', '', '')
  }

  // 图形验证码
  if (p.authType === 'AUTH_TYPE_RAND') {
    // p.randImageBase64 为 base64 PNG,可直接绑定到 <image>
    doSecondaryAuth('AUTH_TYPE_RAND', code, username, password, '')
  }

  // 动态口令
  if (p.authType.startsWith('AUTH_TYPE_TOKEN')) {
    doSecondaryAuth(p.authType, code, '', '', '')
  }

  // 密码到期需重置
  if (p.authType === 'AUTH_TYPE_RENEW_PASSWORD') {
    doRenewPasswordAuth(oldPwd, newPwd)
  }

  // 多选一服务
  if (p.services.length > 1) {
    // 让用户选择后,带上 authId 提交
    doSecondaryAuth(p.authType, code, '', '', selectedAuthId)
  }
})

// 5. 注销
logout()

已知约束与踩坑

  1. UTS 插件只能导出函数,无法导出常量/类型:import { ATRUST_EVENTS } from '@/uni_modules/atrust-sdk' 会编译失败,事件名必须在项目侧 config/atrust.config.ts 中定义。
  2. uni.$emit 跨 JS 桥只支持 JSON 兼容类型:自定义 UTS 类型(如 ATrustAuthResult)无法直接过桥,插件内部已自动 JSON.stringify(),页面侧需 JSON.parse<T>() 还原。
  3. SDK 回调不在主线程:插件内部已通过 UTSAndroid.getDispatcher('main').async() 切回主线程后再 emit,页面无需额外处理。
  4. 认证失败后可重试:doSecondaryAuth 不做 authInProgress 前置检查,认证失败(如验证码错误)后 3 分钟内仍可重新提交,无需重新调用 startPasswordAuth。
  5. x86 模拟器不支持:SangforSDK 未提供 x86 so,请使用 ARM 真机调试。
  6. 修改插件后需重新制作自定义调试基座:页面热更新不会生效 UTS 插件改动。

调试

HBuilderX → 运行 → 运行到手机或模拟器 → 制作自定义调试基座 → ARM 真机 运行。

日志统一带 [ATrust] 前缀,可在 HBuilderX 控制台或 adb logcat 中过滤:

adb logcat -s ATrust:D

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。