feat(auth): 实现基于Passkey的登录功能
- 添加了对Web Credentials API的支持- 实现了Passkey注册与认证流程 - 引入了TDesign Button组件用于登录按钮 - 更新了页面加载及过渡动画逻辑- 添加了对不支持Passkey设备的降级处理 - 安装并配置了tdesign-icons-vue-next依赖库
This commit is contained in:
parent
a2ab4b8bb3
commit
5abf344572
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -20,5 +20,6 @@ declare module 'vue' {
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
TAvatar: typeof import('tdesign-mobile-vue')['Avatar']
|
||||
TButton: typeof import('tdesign-mobile-vue')['Button']
|
||||
}
|
||||
}
|
||||
|
||||
1
package-lock.json
generated
1
package-lock.json
generated
@ -12,6 +12,7 @@
|
||||
"pinia": "^3.0.3",
|
||||
"sass-loader": "^16.0.6",
|
||||
"scss": "^0.2.4",
|
||||
"tdesign-icons-vue-next": "^0.4.1",
|
||||
"tdesign-mobile-vue": "^1.11.0",
|
||||
"vue": "^3.5.22",
|
||||
"vue-router": "^4.6.3"
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
"pinia": "^3.0.3",
|
||||
"sass-loader": "^16.0.6",
|
||||
"scss": "^0.2.4",
|
||||
"tdesign-icons-vue-next": "^0.4.1",
|
||||
"tdesign-mobile-vue": "^1.11.0",
|
||||
"vue": "^3.5.22",
|
||||
"vue-router": "^4.6.3"
|
||||
|
||||
61
src/App.vue
61
src/App.vue
@ -5,22 +5,24 @@
|
||||
<span v-if="showTitle" class="title">你好,{{ name }}</span>
|
||||
</transition>
|
||||
<div class="login-info">
|
||||
<transition name="slide-up">
|
||||
<div v-if="!weCome">
|
||||
<transition name="slide-up" mode="out-in">
|
||||
<div v-if="!login">
|
||||
<t-button :disabled="!passkey" @click="handleLogin">登录</t-button>
|
||||
</div>
|
||||
<div v-else-if="!weCome">
|
||||
<transition name="slide-up" mode="out-in">
|
||||
<div v-if="login">
|
||||
<div class="loading" />
|
||||
</div>
|
||||
<div v-else>你好,{{ name }}</div>
|
||||
</transition>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</header>
|
||||
<div class="header-placeholder"/>
|
||||
<div class="header-placeholder" />
|
||||
|
||||
<div id="operable-box">
|
||||
<RouterView v-if="login" ref="routerView" #default="{ Component }">
|
||||
<RouterView v-if="login" #default="{ Component }">
|
||||
<transition name="slide-up" mode="out-in">
|
||||
<component :is="Component" />
|
||||
</transition>
|
||||
@ -33,16 +35,49 @@ import { RouterView } from 'vue-router'
|
||||
import { ref, watch } from 'vue'
|
||||
import avatar from '@/assets/logo.svg'
|
||||
|
||||
const login = ref(true)
|
||||
const weCome = ref(true)
|
||||
const hideLoading = ref(true)
|
||||
const showTitle = ref(true)
|
||||
const login = ref(false)
|
||||
const weCome = ref(false)
|
||||
const hideLoading = ref(false)
|
||||
const showTitle = ref(false)
|
||||
|
||||
const passkey = ref(true)
|
||||
const name = ref('Amico')
|
||||
// mock login
|
||||
setTimeout(() => {
|
||||
|
||||
if (!navigator.credentials) {
|
||||
passkey.value = false
|
||||
}
|
||||
|
||||
function handleLogin(){
|
||||
navigator.credentials.create({
|
||||
publicKey: {
|
||||
challenge: new Uint8Array(32),
|
||||
timeout: 60000,
|
||||
rp: {
|
||||
id: window.location.host,
|
||||
name: "Animo"
|
||||
},
|
||||
user: {
|
||||
id: new Uint8Array(32),
|
||||
name: "Amico",
|
||||
displayName: "Amico",
|
||||
},
|
||||
pubKeyCredParams: [{
|
||||
alg: -7, type: "public-key"
|
||||
},{
|
||||
alg: -257, type: "public-key"
|
||||
}],
|
||||
excludeCredentials: [],
|
||||
authenticatorSelection: {
|
||||
authenticatorAttachment: "platform",
|
||||
requireResidentKey: true,
|
||||
}
|
||||
},
|
||||
}).then(resp => {
|
||||
login.value = true
|
||||
}, 1000)
|
||||
const routerView = ref()
|
||||
})
|
||||
}
|
||||
|
||||
// 登录动画流程
|
||||
watch(login, (val) => {
|
||||
if (val) {
|
||||
setTimeout(() => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user