更新记录
1.0.0(2025-08-01)
支持 android passkey 通行密钥
平台兼容性
云端兼容性
uni-app(4.63)
Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
√ |
√ |
- |
- |
- |
- |
11.0 |
- |
- |
微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
快应用-华为 |
快应用-联盟 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
uni-app x(4.62)
Chrome |
Safari |
Android |
iOS |
鸿蒙 |
微信小程序 |
- |
- |
11.0 |
- |
- |
- |
示例使用
点击右边“使用HBuilderX导入示例项目”,导入示例后免费试用插件或者购买后导入,然后打包自定义android基座。再运行到设备
效果视频(可在抖音或者直接复制链接浏览器打开看)
演示视频链接,点击观看
平台兼容性
目前支持Android,CPU类型支持arm64-v8a,armeabi-v7a android
需要支持iOS请合作,支援我下付费的开发者账号
插件功能
- 账号密码使用passkey方式保存在本机
- public key本地保存
在线使用插件通用流程
- 购买此插件,选择该插件绑定的项目(使用者项目)。
- 购买页面导入到相应项目。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包。
插件API的使用
引入插件
import {PassKeyOptions,saveUserAndPassword,getUserAndPassword,savePublicKeyCredential,getPublicKeyCredential } from "@/uni_modules/xt-passkey-plugin"
API使用 (api30以上的境外版本机器支持,大陆机器部分支持,看厂商的支持情况。)
账号密码 (实际完成测试)
//保存账号密码,一般在用户输入后登录成功保存。当然其他参数,你可以放到里面,自己做解析即可
function saveUserAndPassword(userId:string, password:string,options : PassKeyOptions)
参数3个,参考下面
使用方式:
saveUserAndPassword(this.username, this.password, {
complete: (res) => {
console.log("saveUserAndPassword callback:" + res);
try {
const result = typeof res === 'string' ? JSON.parse(res) : res;
this.callbackText = `保存结果: ${JSON.stringify(result)}`;
} catch (e) {
console.error('Error parsing save result:', e);
this.callbackText = `保存出错: ${e.message}`;
}
},
});
返回值:成功如下,其他均为失败
{
"status": "success",
"type": "save"
}
//获取已保存的密码,一般在点击输入框或者进入登录页面时调用
export function getUserAndPassword(options : PassKeyOptions)
参数1个,参考下面
getUserAndPassword({
complete: (res) => {
console.log("getUserAndPassword callback:" + res);
try {
// Parse the JSON string if it's a string
const result = typeof res === 'string' ? JSON.parse(res) : res;
this.callbackText = `获取结果: ${JSON.stringify(result)}`;
if (result.status === 'success' && result.type === 'get') {
this.username = result.userId || '';
this.password = result.password || '';
}
} catch (e) {
console.error('Error parsing user data:', e);
this.callbackText = `获取出错: ${e.message}`;
}
},
});
返回值:成功如下,其他均为失败
{
"status": "success",
"type": "get",
"userId": "Hfhdj",
"password": "jdjjfjf"
}
public key (由于环境限制,我这边无法完成测试,需要自己的域名和相对应的签名)
//保存publickey
function savePublicKeyCredential(registrationJson:string,options : PassKeyOptions)
registrationJson格式如下:
{
"attestation": "none",
"authenticatorSelection": {
"authenticatorAttachment": "platform",
"requireResidentKey": false,
"residentKey": "required",
"userVerification": "required"
},
"challenge": "5_1HW194lz90hxhZ_L-Dc2eCl21fawKf6XmT6gXIOn0",
"excludeCredentials": [],
"pubKeyCredParams": [
{
"alg": -7,
"type": "public-key"
}
],
"rp": {
"id": "dashlane-passkey-demo.glitch.me",
"name": "Dashlane Passkey Demo"
},
"timeout": 1800000,
"user": {
"displayName": "hfhdj@jdjdj.com",
"id": "e656e3e0-cb19-44d3-98c4-9a8a3f50be2e",
"name": "hfhdj@jdjdj.com"
}
}
返回结果和前面类似
//获取publickey
function getPublicKeyCredential(authJson :string, options : PassKeyOptions)
authJson 参数如下:
{
"challenge": "<challenge_string>",
"allowCredentials": [
{
"id": "<credential_id>",
"transports": ["internal", "hybrid"],
"type": "public-key"
}
],
"timeout": 1800000,
"userVerification": "required",
"rpId": "dashlane-passkey-demo.glitch.me"
}
返回结果和前面类似
uniapp主页代码
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<!-- 用户名输入框 -->
<view class="input-group">
<text class="input-label">用户名:</text>
<input class="input" v-model="username" placeholder="请输入用户名" />
</view>
<!-- 密码输入框 -->
<view class="input-group">
<text class="input-label">密码:</text>
<input class="input" v-model="password" password placeholder="请输入密码" />
</view>
<!-- 登录按钮 -->
<button class="login-btn" @click="handleLogin">登录</button>
<!-- 新增的简单文本显示框 -->
<text style="width:80%; margin-top:20rpx; display:block; text-align:center; word-wrap:break-word; white-space:pre-wrap;">{{callbackText}}</text>
</view>
</template>
<script>
import {PassKeyOptions,saveUserAndPassword,getUserAndPassword,savePublicKeyCredential,getPublicKeyCredential } from "@/uni_modules/xt-passkey-plugin"
export default {
data() {
return {
title: '登录页面',
username: '',
password: '',
callbackText: ''
}
},
onLoad() {
getUserAndPassword({
complete: (res) => {
console.log("getUserAndPassword callback:" + res);
try {
// Parse the JSON string if it's a string
const result = typeof res === 'string' ? JSON.parse(res) : res;
this.callbackText = `获取结果: ${JSON.stringify(result)}`;
if (result.status === 'success' && result.type === 'get') {
this.username = result.userId || '';
this.password = result.password || '';
}
} catch (e) {
console.error('Error parsing user data:', e);
this.callbackText = `获取出错: ${e.message}`;
}
},
});
},
methods: {
handleLogin() {
// 获取用户名和密码
console.log('用户名:', this.username);
console.log('密码:', this.password);
// 判空处理
if (!this.username || !this.password) {
uni.showToast({
title: '用户名和密码不能为空',
icon: 'none',
duration: 2000
});
return;
}
saveUserAndPassword(this.username, this.password, {
complete: (res) => {
console.log("saveUserAndPassword callback:" + res);
try {
const result = typeof res === 'string' ? JSON.parse(res) : res;
this.callbackText = `保存结果: ${JSON.stringify(result)}`;
} catch (e) {
console.error('Error parsing save result:', e);
this.callbackText = `保存出错: ${e.message}`;
}
},
});
// 这里可以添加登录逻辑,比如调用API
uni.showToast({
title: `登录中: ${this.username}`,
icon: 'loading'
});
// 模拟登录请求
setTimeout(() => {
uni.showToast({
title: '登录成功',
icon: 'success'
});
// 实际开发中可以在这里跳转到首页
}, 1500);
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
margin-bottom: 50rpx;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
/* 输入框组样式 */
.input-group {
width: 80%;
margin-bottom: 30rpx;
display: flex;
align-items: center;
}
.input-label {
width: 150rpx;
font-size: 30rpx;
color: #333;
}
.input {
flex: 1;
height: 80rpx;
padding: 0 20rpx;
border: 1rpx solid #ddd;
border-radius: 8rpx;
font-size: 28rpx;
}
/* 登录按钮样式 */
.login-btn {
width: 80%;
height: 90rpx;
line-height: 90rpx;
margin-top: 50rpx;
background-color: #007AFF;
color: white;
font-size: 32rpx;
border-radius: 45rpx;
}
.login-btn:active {
background-color: #0062CC;
}
</style>