enhance: user token storage

This commit is contained in:
Jacky 2024-10-23 11:48:58 +08:00
parent 925e61abf4
commit 59947a35db
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
5 changed files with 66 additions and 48 deletions

View file

@ -46,7 +46,7 @@ async function passkeyAuthenticate() {
passkeyLoading.value = true
try {
const begin = await twoFA.begin_start_secure_session_by_passkey()
const asseResp = await startAuthentication(begin.options.publicKey)
const asseResp = await startAuthentication({ optionsJSON: begin.options.publicKey })
const r = await twoFA.finish_start_secure_session_by_passkey({
session_id: begin.session_id,

View file

@ -1,6 +1,5 @@
import { createVNode, render } from 'vue'
import { Modal, message } from 'ant-design-vue'
import { useCookies } from '@vueuse/integrations/useCookies'
import Authorization from '@/components/TwoFA/Authorization.vue'
import twoFA from '@/api/2fa'
import { useUserStore } from '@/pinia'
@ -32,11 +31,8 @@ const use2FAModal = () => {
return
}
const cookies = useCookies(['nginx-ui-2fa'])
const ssid = cookies.get('secure_session_id')
if (ssid && secureSessionStatus) {
resolve(ssid)
secureSessionId.value = ssid
if (secureSessionId.value && secureSessionStatus) {
resolve(secureSessionId.value)
return
}
@ -51,7 +47,6 @@ const use2FAModal = () => {
}
const setSessionId = (sessionId: string) => {
cookies.set('secure_session_id', sessionId, { maxAge: 60 * 3 })
close()
secureSessionId.value = sessionId
resolve(sessionId)

View file

@ -1,6 +1,5 @@
import type { AxiosRequestConfig } from 'axios'
import axios from 'axios'
import { useCookies } from '@vueuse/integrations/useCookies'
import { storeToRefs } from 'pinia'
import NProgress from 'nprogress'
import { useSettingsStore, useUserStore } from '@/pinia'
@ -62,10 +61,9 @@ instance.interceptors.response.use(
NProgress.done()
const otpModal = use2FAModal()
const cookies = useCookies(['nginx-ui-2fa'])
switch (error.response.status) {
case 401:
cookies.remove('secure_session_id')
secureSessionId.value = ''
await otpModal.open()
break
case 403:

View file

@ -1,34 +1,64 @@
import { defineStore } from 'pinia'
import { useCookies } from '@vueuse/integrations/useCookies'
import type { CookieChangeOptions } from 'universal-cookie'
export const useUserStore = defineStore('user', {
state: () => ({
token: '',
unreadCount: 0,
secureSessionId: '',
passkeyRawId: '',
}),
getters: {
isLogin(state): boolean {
return !!state.token
},
passkeyLoginAvailable(state): boolean {
return !!state.passkeyRawId
},
},
actions: {
passkeyLogin(rawId: string, token: string) {
this.passkeyRawId = rawId
this.login(token)
},
login(token: string) {
this.token = token
},
logout() {
this.token = ''
this.passkeyRawId = ''
this.secureSessionId = ''
this.unreadCount = 0
},
},
export const useUserStore = defineStore('user', () => {
const cookies = useCookies(['nginx-ui'])
const token = ref('')
watch(token, v => {
cookies.set('token', v, { maxAge: 86400 })
})
const secureSessionId = ref('')
watch(secureSessionId, v => {
cookies.set('secure_session_id', v, { maxAge: 60 * 3 })
})
function handleCookieChange({ name, value }: CookieChangeOptions) {
if (name === 'token')
token.value = value
else if (name === 'secure_session_id')
secureSessionId.value = value
}
cookies.addChangeListener(handleCookieChange)
const passkeyRawId = ref('')
const unreadCount = ref(0)
const isLogin = computed(() => !!token.value)
const passkeyLoginAvailable = computed(() => !!passkeyRawId.value)
function passkeyLogin(rawId: string, tokenValue: string) {
passkeyRawId.value = rawId
login(tokenValue)
}
function login(tokenValue: string) {
token.value = tokenValue
}
function logout() {
token.value = ''
passkeyRawId.value = ''
secureSessionId.value = ''
unreadCount.value = 0
}
return {
token,
unreadCount,
secureSessionId,
passkeyRawId,
isLogin,
passkeyLoginAvailable,
passkeyLogin,
login,
logout,
}
}, {
persist: true,
})

View file

@ -1,7 +1,6 @@
<script setup lang="ts">
import { KeyOutlined, LockOutlined, UserOutlined } from '@ant-design/icons-vue'
import { Form, message } from 'ant-design-vue'
import { useCookies } from '@vueuse/integrations/useCookies'
import { startAuthentication } from '@simplewebauthn/browser'
import { useUserStore } from '@/pinia'
import auth from '@/api/auth'
@ -60,13 +59,12 @@ const onSubmit = () => {
await auth.login(modelRef.username, modelRef.password, passcode.value, recoveryCode.value).then(async r => {
const next = (route.query?.next || '').toString() || '/'
const cookies = useCookies(['nginx-ui-2fa'])
switch (r.code) {
case 200:
message.success($gettext('Login successful'), 1)
login(r.token)
await nextTick()
secureSessionId.value = r.secure_session_id
cookies.set('secure_session_id', r.secure_session_id, { maxAge: 60 * 3 })
await router.push(next)
break
case 199:
@ -159,7 +157,7 @@ async function handlePasskeyLogin() {
passkeyLoginLoading.value = true
try {
const begin = await auth.begin_passkey_login()
const asseResp = await startAuthentication(begin.options.publicKey)
const asseResp = await startAuthentication({ optionsJSON: begin.options.publicKey })
const r = await auth.finish_passkey_login({
session_id: begin.session_id,
@ -167,13 +165,10 @@ async function handlePasskeyLogin() {
})
if (r.token) {
const cookies = useCookies(['nginx-ui-2fa'])
const next = (route.query?.next || '').toString() || '/'
passkeyLogin(asseResp.rawId, r.token)
secureSessionId.value = r.secure_session_id
cookies.set('secure_session_id', r.secure_session_id, { maxAge: 60 * 3 })
await router.push(next)
}
}