vpn_sdp 2.0.8 copy "vpn_sdp: ^2.0.8" to clipboard
vpn_sdp: ^2.0.8 copied to clipboard

SDP 版本 VPN 接入 Flutter 插件,基于零信任 SDP 安全隧道 SDK 封装,提供 iOS/Android 双平台 VPN 连接管理能力。

vpn_sdp #

SDP 版本 VPN 接入 Flutter 插件,基于零信任 SDP 安全隧道 SDK 封装,提供 iOS/Android 双平台 VPN 连接管理能力。

如果此文档显示不正常,请点击《VPN_SDP Flutter插件文档》跳转至语雀查看

一、使用前准备 #

注:在使用插件之前,需要大概过一下SDP厂商提供的接入文档,熟悉VPN的基本原理和使用流程,此插件依据厂商提供的《 零信任SDP移动终端(SDK)安全隧道接入方案V1.0 》文档和Demo基础上编写而成

1.1. iOS接入流程 #

1.1.1 框架导入准备
  • 在主工程iOS目录下创建Frameworks文件夹
  • 将AiSDPsk框架文件及AiSDPskBundle.bundle资源包拖入该目录
  • 通过Xcode右键菜单打开项目
1.1.2 创建网络扩展Target
  • 在Xcode左侧目录选择Runner项目
  • 点击TARGETS区域的"+"按钮
  • 搜索并选择"Network Extension"模板
  • 按向导完成创建(建议命名如"Tun")
1.1.3 基础配置
  • 开发团队选择对应的Apple开发者账号
  • 编程语言统一选择Swift(包括OC兼容设置)
  • 设置唯一的Bundle Identifier(格式示例:com.company.vpn.Tun)
1.1.4 能力配置
  • 主Target和扩展Target均需添加:
    • Network Extensions(勾选Packet Tunnel)
    • Personal VPN能力
  • 在扩展Target的Frameworks中:
    • 添加AiSDPsk.framework(从主工程选择)
    • 设置Embed选项为"Do Not Embed"
1.1.5 主工程配置
  • 确保主Target的Frameworks包含所有必需框架
  • 设置Embed模式为"Embed & Sign"
1.1.6 集成代码
import NetworkExtension
import AiSDPsdk
final class PacketTunnelProvider: PacketTunnelProviderSDK {}

1.2. Android 接入 #

在应用启动之初,需要请求android.permission.BLUETOOTH_CONNECT权限,否则所有关于vpn连接的请求都将出现如下异常:

D/UDP     ( 6317): 认证通道创建异常: Need android.permission.BLUETOOTH_CONNECT permission for AttributionSource { uid = 10421, packageName = com.gzdict.vpn_sdp_example, attributionTag = null, token = android.os.BinderProxy@37f742a, next = null }: getName
[   +2 ms] W/System.err( 6317): java.lang.SecurityException: Need android.permission.BLUETOOTH_CONNECT permission for AttributionSource { uid = 10421, packageName = com.gzdict.vpn_sdp_example, attributionTag = null, token = android.os.BinderProxy@37f742a, next = null }: getName
[        ] W/System.err( 6317): 	at android.os.Parcel.createExceptionOrNull(Parcel.java:2438)
[   +2 ms] W/System.err( 6317): 	at android.os.Parcel.createException(Parcel.java:2422)
[        ] W/System.err( 6317): 	at android.os.Parcel.readException(Parcel.java:2405)
[        ] W/System.err( 6317): 	at android.os.Parcel.readException(Parcel.java:2347)
[        ] W/System.err( 6317): 	at android.bluetooth.IBluetoothManager$Stub$Proxy.getName(IBluetoothManager.java:1194)
[        ] W/System.err( 6317): 	at android.bluetooth.BluetoothAdapter.getName(BluetoothAdapter.java:2345)
[        ] W/System.err( 6317): 	at com.aisec.sdp.util.InterfaceV2Method.verifyV2(InterfaceV2Method.java:61)
[        ] W/System.err( 6317): 	at com.aisec.sdp.thread.UdpAuthV2Thread.run(UdpAuthV2Thread.java:111)

关于权限请求,建议使用permission_handler插件处理,例如:

  void _requestPermission() async {
    if (!Platform.isAndroid) {
      return;
    }
    var result = await Permission.bluetoothConnect.request();
    if (!result.isGranted) {
      /// 无权限,不可操作
    }
  }

接入插件,第一次调用连接方法成功后,会出现如下弹窗;点击确认后,状态栏会出现小钥匙的图标,此时就代表接入成功

1.3. Android 依赖说明(compileOnly) #

本插件的 Android 端依赖(SDP 厂商 SDK aar、fastjson、dnsjava、bcpkix-jdk15to18、sunjce_provider.jar)均以 compileOnly 方式引入,不会随插件打包进宿主工程。宿主 App 需要自行集成这些依赖,否则运行时会抛出 NoClassDefFoundError / ClassNotFoundException 异常。

插件仓库中已不再附带 android/libs 目录(原包含 sdp-release-3.8.7.131_20240725.aarsunjce_provider.jar),且插件 android/build.gradle不声明任何本地文件依赖,以上依赖必须由宿主工程完整提供,否则宿主工程编译时会因缺少文件导致构建失败(如 JetifyTransform 报错)。如需本地开发,请向 SDP 厂商获取对应的 aar 放入宿主工程的 libs 目录,并在宿主工程的 build.gradle 中配置 flatDir 仓库及相应依赖(参考以下示例):

repositories {
    flatDir { dirs 'libs' }
}

dependencies {
    implementation(name: 'sdp-release-3.8.7.131_20240725', ext: 'aar')
    implementation 'com.alibaba:fastjson:1.2.70'
    implementation 'dnsjava:dnsjava:2.1.7'
    implementation 'org.bouncycastle:bcpkix-jdk15to18:1.68'
    implementation files('libs/sunjce_provider.jar')
}

二、接口说明 #

2.1. verifyV3 #

特别注意:

  1. 在Android端,此方法会同[proxyApiV2]以及[reconnect]方法互斥
  2. 在iOS端,此方法会同[reconnect]方法互斥

2.1.1. VPN三方认证登录,因为SDP需要知晓是否认证成功,所以需要外围系统对返回格式进行改造:

参数 说明
code 【0:成功 ;1:失败; 2:需要下一步认证】
desc 描述
nextcmd 二次认证方式:sms email otp
userName 账号
data 接口需要返回给APP的数据,SDP会做透传

2.1.2. 参数如下:

114.135.115.224
55840
reqUrl 第三方的认证请求URL
method http调用方式,传递post、get post
header 使用json格式
reqType
请求方式:【1,2】,含义如下
1:健值对格式
2:body方式
2

当传输方式选择1:使用json格式传递健值对
当传输方式选择2:使用字符串,SDP会透传
function string
timeout Duration 防止插件异常导致结果无返回,设置一个超时时间 15秒

2.2. proxyApiV2 #

接口透传,返回透传结果,透传返回值亦可通过[messageStream]监听,code为[MethodCode.proxyApi]

  • 在Android端,此方法会同[verifyV3]以及[reconnect]方法互斥

2.2.1. 对第三方接口进行透传,

参数说明:

reqUrl 第三方的数据请求URL
method http调用方式,传递post、get
header 使用json格式
reqType
请求方式:【1,2】,含义如下
1:健值对格式
2:body方式

当传输方式选择1:使用json格式传递健值对
当传输方式选择2:使用字符串,SDP会透传

#

2.3. reconnect vpn重连,无参数

  • 在Android端,此方法会同[verifyV3]以及[proxyApiV2]方法互斥
  • 在iOS端,此方法会同[verifyV3]方法互斥

2.4. disconnect #

断开vpn连接,之后[messageStream]会接收到[RltCode.disconnect]消息。

2.5. messageStream #

监听消息,返回[SdpResult],其中code和data字段如下:

{
  "code":0, #状态码
  "data": {} #返回值,可能是json格式,也可能是字符串
}

2.6. setUp #

初始化参数,仅iOS有效

变量名 类型 描述 默认值
sn String 设备序列号 000000000000
vpnLocalizedDesc String vpn描述,用于在系统设置Vpn列表中显示 VPN_SDP
mac String 设备mac 00:00:00:00:00:00
providerBundleId String NetworkExtension的bundleId,例如com.example.vpn.tun

三、示例 #

3.1.1. 初始化

# 依赖vpn_sdp
vpn_sdp: ^2.0.6

// 实例化vpn插件
final _vpnSdpPlugin = VpnSdp();

/// 如果有iOS,必须先调用此方法
_vpnSdpPlugin.setUp(
  providerBundleId: "com.gzdict.gzyqdev.Tun",
);

/// Android端请求权限
if (!Platform.isAndroid) {
      return;
    }
    var result = await Permission.bluetoothConnect.request();
    if (!result.isGranted) {
      /// 无权限,不可操作
    }

3.2.2. 连接

var url = "${netDio.options.baseUrl}/km/sso/sdpLogin";
var msgCode = await _msgCode.rsaEncode();
var password = await _password.rsaEncode();
var body = {
  "username": _username,
  "password": password,
  "captchaCode": msgCode,
};
// 在此调用verifyV3开启vpn
var result = await _vpnSdpPlugin
  .verifyV3(username: _username, reqUrl: url, body: body, func: "yxt")
  .toDialogRequest()
  .start();
if (result != null) {
  _transformData(result);
}

3.2.3. 断开连接

// 手动断开连接,一般在退出登录时调用
await _vpnSdpPlugin.disconnect();

3.2.4. 重连

手动重连,SDK内设置了主动重连功能,一般无需调用,仅在某些特殊情况提供此功能
await _vpnSdpPlugin.reconnect()

3.2.5. 透传

var url = "${netDio.options.baseUrl}/km/sso/sdpVerify";
var password = await _password.rsaEncode();
var data = {
  "username": _username,
  "password": password,
  "captchaType": 0,
};
var result = await _vpnSdpPlugin
  .proxyApiV2(
  reqUrl: url,
  body: data,
)
  .toDialogRequest()
  .start();
if (result != null) {
  SmartDialog.showToast(result.toString());
}

3.2.6. 监听vpn返回的所有状态


StreamSubscription? _subscription;

.....
  
_subscription = _vpnSdpPlugin.messageStream.listen(
  (data) {
    setState(() {
      _resultStr = "$data";
    });
  },
  onError: (error) {
    setState(() {
      _resultStr = "$error";
    });
  },
);

四、错误码 #

以下错误均SDP提供,可能存在不完整情况,仅做参考;

4.1. Android 错误码 #

code 错误提示 报错原因 备注
1001 认证失败 认证接口返回的报错 第三方APPServer错误都在此处提示
1003 创建虚拟网卡失败 创建虚拟网卡失败 再认证成功后或者断链重新创建VPN失败情况会出现
1015 无法连接到服务器 连接SDP服务器超时 (网络不通环境下会报此错误)
1016 异常中断 SDP服务端交互异常
1019 服务器连接超时 连接SDP服务器超时 (网络不通环境下会报此错误)
1025 连接失败 SDP控制器断开连接 (网络不通环境下会报此错误)
1040 验证读取超时异常 无法连接到SDP服务器 (网络不通环境下会报此错误)
1045 认证成功,vpn通道已存在 重复创建VPN 如果手机已存在VPN也会报此错
9999 重新连接中...连接状态:true/false 正在进行重连 (10S检测一次,检测到连接失败就开始重连)
else 后端返回的错误 交互异常

4.2. iOS 错误码 #

调用SDK连接的时候,新增回调方法TunConnectedWithCode的回调处理,红色code码为常见错误

(原TunConnected回调也保留,只不过没有code )

code(后续补充) 错误提示 报错原因 备注
1001 获取控制器地址或端口为空 服务器地址或端口设置 参数未初始化,或者是服务端配置的控制器地址未空
1002
敲门包发送异常,请稍后重试! 网络不通,SPA敲门超时 (网络不通环境下会报此错误)
1003 连接超时 敲门包发送超时了
这种一般网络是正常的,但是SDP的敲门包发送出现问题,因为有些运营商会拦截SDP的敲门包;或者网络不好,敲门包发送超时了
1004 敲门超时 敲门包发送超时 (网络不通环境下会报此错误)
1005 连接关闭 SDK与服务端的连接断开了 一般是用户主动关闭连接,或者网络断开,服务被关闭的时候
2001 连接服务器失败 与SDP控制器连接失败 可能是控制器地址连接超时或sdp服务出现异常了
2002 创建虚拟网卡失败 网关连接超时 多次重连也会存在此异常,或者sdk的refreshkey过期了,sdk重连也会发生
2004 会话过期,请重新登录 refreshkey到期了
管理平台设置的会话到期时间一般是8小时,重连sdk会话已到期,需重新登录
2003 敲门绑定失败 敲门bind失败 网络异常了,建议切换网络或重启手机
3001 虚拟网卡启动配置错误 配置vpn出现异常 一般是系统出现异常了,建议重启手机
3002 vpn异常断开 VPN被其他app或人为关闭 app之间抢占vpn;或进入设置页手动关闭vpn
else 后端返回的错误 SDP服务端或者第三方认证服务错误

调用SDK发送透传请求,调用proxyApi/proxyApiV2回调

code 提示信息(Any对象) 报错原因 备注
1002 敲门包发送异常,请稍后重试! 敲门包发送超时了 这种一般网络是正常的,但是SDP的敲门包发送出现问题,因为有些运营商会拦截SDP的敲门包;或者网络不好,敲门包发送超时了
1004 敲门超时 敲门包发送超时 (网络不通环境下会报此错误)
else 后端返回的错误 SDP服务端或者第三方认证服务错误
0
likes
105
points
110
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

SDP 版本 VPN 接入 Flutter 插件,基于零信任 SDP 安全隧道 SDK 封装,提供 iOS/Android 双平台 VPN 连接管理能力。

Repository

License

MIT (license)

Dependencies

flutter, package_info, permission_handler, plugin_platform_interface

More

Packages that depend on vpn_sdp

Packages that implement vpn_sdp