mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-10 18:05:48 +02:00
enhance: user token storage
This commit is contained in:
parent
925e61abf4
commit
59947a35db
5 changed files with 66 additions and 48 deletions
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue