更新记录
1.0.0(2026-06-18)
首次发布
平台兼容性
uni-app(4.0)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | 5.0 | 15 | 12 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | × | √ |
sangfor-vpn-sdk
本uts插件支持 uni-app 和 uni-app x 项目,推荐先下载示例项目(uni-app)进行试用。
本地调试、开发、试用时,安卓端和iOS端都需要打包自定义基座。
深信服SDK仅支持armeabi-v7a、 arm64-v8a架构模拟器, 不支持X86架构模拟器。
推荐使用真机进行调试、开发、试用。
uniappx工程的鸿蒙端只支持源码授权。
深信服SDK鸿蒙端的getAuthStatus与安卓端、iOS端调用方式和返回值都不一样,具体getAuthStatus使用方式请看示例代码
插件使用示例
uniapp demo
vue3 界面
<template>
<view class="main-page-wrapper" style="padding: 5px 10px;">
<view class="main-auth-wrapper">
<view class="row-item">
<text class="title">服务器:</text>
<input type="url" class="input-wrapper" placeholder="请输入服务器地址" v-model="vpnAddress" />
</view>
<view class="row-item">
<text class="title">账 号:</text>
<input class="input-wrapper" placeholder="请输入账号" v-model="vpnUserName" />
</view>
<view class="row-item">
<text class="title">密 码:</text>
<input class="input-wrapper" placeholder="请输入密码" v-model="vpnUserPassword" />
</view>
<view>
<button type="default" @click="loginVPNMianAuth()" plain="true">开始账号密码主认证</button>
</view>
</view>
<!-- 图形辅助认证 -->
<view v-if="showRandCode" class="rand-code-wrapper">
<view class="rand-code-img-wrapper">
<input v-model="userRandCode" style="width: 400rpx; height: 80rpx; border: solid 1px #ddd;" placeholder="请输入图形验证码" />
<view @click="getRandCode()" style="width: 80px; background-color: black; height: 40px; border: solid 1px #ddd;">
<image :src="randCodeBase64" style="width: 100%; height: 100%; "></image>
</view>
</view>
<view>
<button type="default" @click="doRandCodeAuth()" plain="true">图形辅助认证</button>
</view>
</view>
<!-- 主动修改密码 -->
<view v-if="activelyModifyPwdShow" class="modify-password-wrapper">
<view class="row-item">
<text class="title">旧密码:</text>
<input class="input-wrapper" placeholder="请输入旧密码" v-model="oldPwd" />
</view>
<view class="row-item">
<text class="title">新密码:</text>
<input class="input-wrapper" placeholder="请输入新密码" v-model="newPwd" />
</view>
<view>
<button type="default" @click="activelyResetPasswordHandle()" plain="true">主动修改密码</button>
</view>
</view>
<!-- 修改初始密码 -->
<view v-if="modifyInitialPwdShow" class="modify-password-wrapper">
<view>
<text v-text="pwsRules"></text>
</view>
<view class="row-item">
<text class="title">初始密码:</text>
<input class="input-wrapper" placeholder="请输入初始密码" v-model="initialOldPwd" />
</view>
<view class="row-item">
<text class="title">新密码:</text>
<input class="input-wrapper" placeholder="请输入新密码" v-model="initialNewPwd" />
</view>
<view>
<button type="default" @click="modifyInitialPasswordHandle()" plain="true">修改初始密码</button>
</view>
</view>
<view class="uni-btn-wrapper">
<button style="margin-bottom: 20rpx;" type="default" @click="getAuthStatusAndShow()" plain="true">获取认证状态</button>
<button style="margin-bottom: 20rpx;" type="default" @click="loginAutoTicketAndShow()" plain="true">免密认证</button>
<button style="margin-bottom: 20rpx;" type="default" @click="allowactivelyResetPasswordHandle()" plain="true">是否支持主动修改密码</button>
<button style="margin-bottom: 20rpx;" type="default" @click="getPswStrategyHandle()" plain="true">获取密码规则</button>
<button style="margin-bottom: 20rpx;" type="default" @click="logoutHandle()" plain="true">注销登录</button>
</view>
</view>
</template>
vue3 js代码
import { onMounted, ref } from 'vue'
import * as sangforVpnSdk from '@/uni_modules/sangfor-vpn-sdk'
const vpnAddress = ref('https://**.**.**.**/')
const vpnUserName = ref('')
const vpnUserPassword = ref('')
const showRandCode = ref(false)
const userRandCode = ref('') // 用户输入的图像验证码
const randCodeBase64 = ref('') // 图像验证码的src
const oldPwd = ref('')
const newPwd = ref('')
const activelyModifyPwdShow = ref(false)
const initialOldPwd = ref('')
const initialNewPwd = ref('')
const modifyInitialPwdShow = ref(false)
const pwsRules = ref('') // 修改初始密码时的密码规则
// 获取认证状态
async function getAuthStatusAndShow() {
uni.showLoading({
title: '请求中'
})
// #ifdef APP-HARMONY
console.log("仅鸿蒙会编译")
const res = await sangforVpnSdk.getAuthStatus()
uni.hideLoading()
if (res) {
uni.showModal({
title: '当前的登录状态为:已认证成功',
showCancel: false
})
} else {
uni.showModal({
title: '当前的登录状态为:未认证成功',
showCancel: false
})
}
// #endif
// #ifndef APP-HARMONY
console.log("仅非鸿蒙会编译")
const res = sangforVpnSdk.getAuthStatus()
uni.hideLoading()
uni.showModal({
title: '当前的登录状态为:' + res,
showCancel: false
})
// #endif
}
// 免密登录
function loginAutoTicketAndShow() {
const res = sangforVpnSdk.startAutoTicket()
if (res) {
uni.showModal({
title: '当前已登录过且支持免密',
showCancel: false
})
} else {
uni.showModal({
title: '当前未登录过或不支持免密',
showCancel: false
})
}
}
// 处理登录结果
function dealAuthResult(result) {
console.log(result)
if (result.message.startsWith("AUTH_")) {
if (result.message === "AUTH_SUCCESS") {
uni.showModal({
title: '账号:' + vpnUserName.value + ',认证成功!',
showCancel: false
});
return
}
if (result.message === 'AUTH_TYPE_RAND') {
// 图像验证码
showRandCode.value = true
getRandCode()
return
}
if (result.message === 'AUTH_TYPE_RENEW_PASSWORD') {
// 修改初始密码
modifyInitialPwdShow.value = true
console.log("result.data.changePwdData is ", result.data.changePwdData)
pwsRules.value = result.data.changePwdData.policyMsg
console.log('pwsRules.value is ', pwsRules.value)
return
}
if (result.message === 'AUTH_TYPE_NOT_SUPPORT') {
// 未支持的AUTH_TYPE
uni.showModal({
title: 'uts插件暂不支持此认证类型,可联系uts插件作者增加',
showCancel: false
});
return
}
} else {
uni.showModal({
title: '认证失败,失败原因是:' + result.message,
showCancel: false
});
return
}
}
// 用户名密码登录
function loginVPNMianAuth() {
console.log('vpnAddress is', vpnAddress.value)
console.log('vpnUserName is', vpnUserName.value)
console.log('vpnUserPassword is', vpnUserPassword.value)
uni.showLoading({
title: '请求中'
})
sangforVpnSdk.startPasswordAuth(vpnAddress.value, vpnUserName.value, vpnUserPassword.value, (result) => {
uni.hideLoading()
dealAuthResult(result)
})
}
// 获取图形验证码
function getRandCode() {
console.log('vue 中 开始 获取 uts regetRandCode')
sangforVpnSdk.regetRandCode((result) => {
console.log('得到的验证码是:', result)
if (result.success) {
randCodeBase64.value = 'data:image/png;base64,' + result.message
} else {
uni.showModal({
title: '获取图形验证码失败',
content: result.message,
showCancel: false
})
}
})
}
// 图形验证
function doRandCodeAuth() {
console.log('vue 中 开始调用 uts doSecondaryAuth')
// 图形验证码验证
sangforVpnSdk.doSecondaryAuth({
u: vpnUserName.value,
p: vpnUserPassword.value,
randCode: userRandCode.value
}, result => {
console.log(result)
if (result.message) {
uni.showModal({
title: '提示',
content: result.message,
showCancel: false
})
} else {
uni.showModal({
title: '提示',
content: result,
showCancel: false
})
}
})
}
// 是否支持主动修改密码
function allowactivelyResetPasswordHandle() {
let res = sangforVpnSdk.allowResetPassword()
console.log(' vue 中 allowactivelyResetPasswordHandle res is ', res)
if (res) {
activelyModifyPwdShow.value = true
uni.showModal({
title: '提示',
content: '当前用户支持主动修改密码',
showCancel: false
})
} else {
uni.showModal({
title: '提示',
content: '当前用户不支持主动修改密码',
showCancel: false
})
}
console.log('支持主动修改密码', res)
}
// 获取密码规则
function getPswStrategyHandle() {
sangforVpnSdk.getPswStrategy(result => {
uni.showModal({
title: '密码规则是:',
content: result.message,
showCancel: false
})
console.log(result)
})
}
// 主动修改密码
function activelyResetPasswordHandle() {
sangforVpnSdk.resetPassword(oldPwd.value, newPwd.value, result => {
console.log(result)
if (result.message) {
uni.showModal({
title: '提示',
content: result.message,
showCancel: false
})
} else {
uni.showModal({
title: '提示',
content: String(result),
showCancel: false
})
}
})
}
// 修改初始密码
function modifyInitialPasswordHandle() {
// 修改初始密码验证
sangforVpnSdk.doSecondaryAuth({
oldPw: initialOldPwd.value,
newPw: initialNewPwd.value,
}, result => {
console.log('modifyInitialPasswordHandle 中 result is ', result)
if (result.message) {
uni.showModal({
title: '提示',
content: result.message,
showCancel: false
})
} else {
console.log('modifyInitialPasswordHandle 中 result is ', result)
uni.showModal({
title: '提示',
content: result,
showCancel: false
})
}
})
}
// 注销登录
function logoutHandle() {
sangforVpnSdk.logout(result => {
uni.showModal({
title: '提示',
content: result.message,
showCancel: false
})
console.log(result)
})
}
onMounted(() => {
console.log("onMounted")
sangforVpnSdk.initSDK()
})
uniappx demo
vue3 界面
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<view class="main-page-wrapper" style="padding: 5px 10px;">
<view class="main-auth-wrapper">
<view class="row-item">
<text class="title">服务器:</text>
<input type="url" class="input-wrapper" placeholder="请输入服务器地址" v-model="vpnAddress" />
</view>
<view class="row-item">
<text class="title">账 号:</text>
<input class="input-wrapper" placeholder="请输入账号" v-model="vpnUserName" />
</view>
<view class="row-item">
<text class="title">密 码:</text>
<input class="input-wrapper" placeholder="请输入密码" v-model="vpnUserPassword" />
</view>
<view>
<button type="default" @click="loginVPNMianAuth()" plain="true">开始账号密码主认证</button>
</view>
</view>
<!-- 图形辅助认证 -->
<view v-if="showRandCode" class="rand-code-wrapper">
<view class="rand-code-img-wrapper">
<input v-model="userRandCode" style="width: 400rpx; height: 80rpx; border: solid 1px #ddd;" placeholder="请输入图形验证码" />
<view @click="getRandCode()" style="width: 80px; background-color: black; height: 40px; border: solid 1px #ddd;">
<image :src="randCodeBase64" style="width: 100%; height: 100%; "></image>
</view>
</view>
<view>
<button type="default" @click="doRandCodeAuth()" plain="true">图形辅助认证</button>
</view>
</view>
<!-- 主动修改密码 -->
<view v-if="activelyModifyPwdShow" class="modify-password-wrapper">
<view class="row-item">
<text class="title">旧密码:</text>
<input class="input-wrapper" placeholder="请输入旧密码" v-model="oldPwd" />
</view>
<view class="row-item">
<text class="title">新密码:</text>
<input class="input-wrapper" placeholder="请输入新密码" v-model="newPwd" />
</view>
<view>
<button type="default" @click="activelyResetPasswordHandle()" plain="true">主动修改密码</button>
</view>
</view>
<!-- 修改初始密码 -->
<view v-if="modifyInitialPwdShow" class="modify-password-wrapper">
<view>
<text>{{ pwsRules }}</text>
</view>
<view class="row-item">
<text class="title">初始密码:</text>
<input class="input-wrapper" placeholder="请输入初始密码" v-model="initialOldPwd" />
</view>
<view class="row-item">
<text class="title">新密码:</text>
<input class="input-wrapper" placeholder="请输入新密码" v-model="initialNewPwd" />
</view>
<view>
<button type="default" @click="modifyInitialPasswordHandle()" plain="true">修改初始密码</button>
</view>
</view>
<view class="uni-btn-wrapper">
<button style="margin-bottom: 20rpx;" type="default" @click="getAuthStatusAndShow()" plain="true">获取认证状态</button>
<button style="margin-bottom: 20rpx;" type="default" @click="loginAutoTicketAndShow()" plain="true">免密认证</button>
<button style="margin-bottom: 20rpx;" type="default" @click="allowResetPasswordHandle()" plain="true">是否支持主动修改密码</button>
<button style="margin-bottom: 20rpx;" type="default" @click="getPswStrategyHandle()" plain="true">获取密码规则</button>
<button style="margin-bottom: 20rpx;" type="default" @click="logoutHandle()" plain="true">注销登录</button>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
vue3 uts代码
import { onMounted } from 'vue'
import * as sangforVpnSdk from '@/uni_modules/sangfor-vpn-sdk' // 引入插件对象
const vpnAddress = ref<string>('https://**.**.**.**/')
const vpnUserName = ref('')
const vpnUserPassword = ref('')
const showRandCode = ref(false)
const userRandCode = ref('') // 用户输入的图像验证码
const randCodeBase64 = ref('') // 图像验证码的src
const oldPwd = ref('')
const newPwd = ref('')
const activelyModifyPwdShow = ref(false)
const initialOldPwd = ref('')
const initialNewPwd = ref('')
const modifyInitialPwdShow = ref(false)
const pwsRules = ref('') // 修改初始密码时的密码规则
// 获取认证状态
async function getAuthStatusAndShow() {
// #ifdef APP-HARMONY
console.log("仅鸿蒙会编译")
const res = await sangforVpnSdk.getAuthStatus()
uni.hideLoading()
if (res) {
uni.showModal({
title: '当前的登录状态为:已认证成功',
showCancel: false
})
} else {
uni.showModal({
title: '当前的登录状态为:未认证成功',
showCancel: false
})
}
// #endif
// #ifndef APP-HARMONY
console.log("仅非鸿蒙会编译")
const res = sangforVpnSdk.getAuthStatus()
uni.showModal({
title: '当前的登录状态为:' + res,
showCancel: false
})
// #endif
}
// 免密登录
function loginAutoTicketAndShow() {
const res = sangforVpnSdk.startAutoTicket()
if (res) {
uni.showModal({
title: '当前已登录过且支持免密',
showCancel: false
})
} else {
uni.showModal({
title: '当前未登录过或不支持免密',
showCancel: false
})
}
}
// 获取图形验证码
function getRandCode() {
console.log('vue 中 开始 获取 uts regetRandCode')
sangforVpnSdk.regetRandCode((result: UTSJSONObject) => {
console.log('得到的验证码是:', result)
if ((result["success"] as boolean) == true) {
randCodeBase64.value = 'data:image/png;base64,' + result.message
} else {
uni.showModal({
title: '获取图形验证码失败',
content: result["message"] as string,
showCancel: false
})
}
})
}
// 处理登录结果
function dealAuthResult(result: UTSJSONObject) {
console.log(result)
const message = result["message"] as string
if (message.startsWith("AUTH_")) {
if (message === "AUTH_SUCCESS") {
uni.showModal({
title: '账号:' + vpnUserName.value + ',认证成功!',
showCancel: false
});
return
}
if (message === 'AUTH_TYPE_RAND') {
// 图像验证码
showRandCode.value = true
getRandCode()
return
}
if (result.message === 'AUTH_TYPE_RENEW_PASSWORD') {
// 修改初始密码
modifyInitialPwdShow.value = true
const data = result.data as UTSJSONObject
const changePwdData = data["changePwdData"] as UTSJSONObject
pwsRules.value = changePwdData["policyMsg"] as string
console.log('pwsRules.value is ', pwsRules.value)
return
}
if (result.message === 'AUTH_TYPE_NOT_SUPPORT') {
// 未支持的AUTH_TYPE
uni.showModal({
title: 'uts插件暂不支持此认证类型,可联系uts插件作者增加',
showCancel: false
});
return
}
} else {
uni.showModal({
title: '认证失败,失败原因是:' + message,
showCancel: false
});
return
}
}
// 用户名密码登录
function loginVPNMianAuth() {
console.log('vpnAddress is', vpnAddress.value)
console.log('vpnUserName is', vpnUserName.value)
console.log('vpnUserPassword is', vpnUserPassword.value)
uni.showLoading({
title: '请求中'
})
sangforVpnSdk.startPasswordAuth(vpnAddress.value, vpnUserName.value, vpnUserPassword.value, (result: UTSJSONObject) => {
uni.hideLoading()
dealAuthResult(result)
})
}
// 图形验证
function doRandCodeAuth() {
console.log('vue 中 开始调用 uts doSecondaryAuth')
//图形验证码验证
sangforVpnSdk.doSecondaryAuth({
u: vpnUserName.value,
p: vpnUserPassword.value,
randCode: userRandCode.value
}, (result: UTSJSONObject) => {
console.log(result)
if (result["success"] as boolean) {
uni.showModal({
title: '提示',
content: result["message"] as string,
showCancel: false
})
} else {
uni.showModal({
title: '提示',
content: result["message"] as string,
showCancel: false
})
}
})
}
// 是否支持主动修改密码
function allowResetPasswordHandle() {
let res = sangforVpnSdk.allowResetPassword()
if (res) {
activelyModifyPwdShow.value = true
uni.showModal({
title: '提示',
content: '当前用户支持主动修改密码',
showCancel: false
})
} else {
uni.showModal({
title: '提示',
content: '当前用户不支持主动修改密码',
showCancel: false
})
}
console.log('支持主动修改密码', res)
}
// 获取密码规则
function getPswStrategyHandle() {
sangforVpnSdk.getPswStrategy((result: UTSJSONObject) => {
uni.showModal({
title: '密码规则是:',
content: result["message"] as string,
showCancel: false
})
console.log(result)
})
}
// 修改密码
function activelyResetPasswordHandle() {
sangforVpnSdk.resetPassword(oldPwd.value, newPwd.value, (result: UTSJSONObject) => {
console.log(result)
if (result["success"] as boolean) {
uni.showModal({
title: '提示',
content: result["message"] as string,
showCancel: false
})
} else {
uni.showModal({
title: '提示',
content: result["message"] as string,
showCancel: false
})
}
})
}
// 修改初始密码
function modifyInitialPasswordHandle() {
// 修改初始密码验证
sangforVpnSdk.doSecondaryAuth({
oldPw: initialOldPwd.value,
newPw: initialNewPwd.value,
}, (result: UTSJSONObject) => {
console.log('modifyInitialPasswordHandle 中 result is ', result)
if (result["success"] as boolean) {
uni.showModal({
title: '提示',
content: result["message"] as string,
showCancel: false
})
} else {
uni.showModal({
title: '提示',
content: result["message"] as string,
showCancel: false
})
}
})
}
// 注销登录
function logoutHandle() {
sangforVpnSdk.logout((result: UTSJSONObject) => {
uni.showModal({
title: '提示',
content: result["message"] as string,
showCancel: false
})
console.log(result)
})
}
onMounted(() => {
console.log("onMounted")
sangforVpnSdk.initSDK()
})
插件功能说明
本插件未包含深信服SDK全部功能。目前插件实现的功能全部在上面demo中展示了。
鸿蒙端支持uniappx项目的特别说明
购买源码后,如需支持uniappx项目,可将SangforManager.ets文件中如下代码:
import {UTSJSONObject} from '@dcloudio/uni-app-runtime'
// import {UTSJSONObject} from '@dcloudio/uni-app-x-runtime'
修改为如下:
// import {UTSJSONObject} from '@dcloudio/uni-app-runtime'
import {UTSJSONObject} from '@dcloudio/uni-app-x-runtime'
即可支持uniapp项目

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 2
赞赏 0
下载 12286069
赞赏 1922
赞赏
京公网安备:11010802035340号