Login bei abgelaufener Sitzung korrigieren
This commit is contained in:
@@ -46,6 +46,15 @@ const doLogin = async (event: FormSubmitEvent<typeof state>) => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<UAlert
|
||||||
|
v-if="auth.sessionExpired"
|
||||||
|
color="warning"
|
||||||
|
variant="soft"
|
||||||
|
icon="i-heroicons-clock"
|
||||||
|
title="Deine Sitzung ist abgelaufen"
|
||||||
|
description="Bitte melde dich erneut an, um weiterzuarbeiten."
|
||||||
|
/>
|
||||||
|
|
||||||
<UForm :state="state" class="space-y-4" @submit="doLogin">
|
<UForm :state="state" class="space-y-4" @submit="doLogin">
|
||||||
<UFormField label="E-Mail" name="email">
|
<UFormField label="E-Mail" name="email">
|
||||||
<UInput
|
<UInput
|
||||||
|
|||||||
@@ -34,12 +34,13 @@ export default defineNuxtPlugin(() => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async onResponseError({ response }) {
|
async onResponseError({ response, request }) {
|
||||||
// Toasts nur im Client anzeigen
|
// Toasts nur im Client anzeigen
|
||||||
console.log(response)
|
console.log(response)
|
||||||
if (!process.client) return
|
if (!process.client) return
|
||||||
|
|
||||||
const status = response.status
|
const status = response.status
|
||||||
|
const requestPath = String(request)
|
||||||
let title = "Fehler"
|
let title = "Fehler"
|
||||||
let description = "Ein unerwarteter Fehler ist aufgetreten."
|
let description = "Ein unerwarteter Fehler ist aufgetreten."
|
||||||
|
|
||||||
@@ -51,7 +52,10 @@ export default defineNuxtPlugin(() => {
|
|||||||
case 401:
|
case 401:
|
||||||
title = "Nicht angemeldet"
|
title = "Nicht angemeldet"
|
||||||
description = "Deine Sitzung ist abgelaufen oder ungültig."
|
description = "Deine Sitzung ist abgelaufen oder ungültig."
|
||||||
// Optional: useCookie('token').value = null
|
if (!requestPath.includes("/auth/login")) {
|
||||||
|
const auth = useAuthStore()
|
||||||
|
auth.expireSession()
|
||||||
|
}
|
||||||
break
|
break
|
||||||
case 403:
|
case 403:
|
||||||
title = "Zugriff verweigert"
|
title = "Zugriff verweigert"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
activeTenantData: null as any,
|
activeTenantData: null as any,
|
||||||
loading: true as boolean,
|
loading: true as boolean,
|
||||||
notLoggedIn: true,
|
notLoggedIn: true,
|
||||||
|
sessionExpired: false,
|
||||||
sessionWarningVisible: false,
|
sessionWarningVisible: false,
|
||||||
sessionWarningRemainingSeconds: 0,
|
sessionWarningRemainingSeconds: 0,
|
||||||
sessionWarningLeadMs: 5 * 60 * 1000,
|
sessionWarningLeadMs: 5 * 60 * 1000,
|
||||||
@@ -105,13 +106,12 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
const msUntilLogout = expiresAtMs - now
|
const msUntilLogout = expiresAtMs - now
|
||||||
|
|
||||||
if (msUntilLogout <= 0) {
|
if (msUntilLogout <= 0) {
|
||||||
void this.logout()
|
this.expireSession()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sessionLogoutTimer = setTimeout(() => {
|
this.sessionLogoutTimer = setTimeout(() => {
|
||||||
this.sessionWarningVisible = false
|
this.expireSession()
|
||||||
void this.logout()
|
|
||||||
}, msUntilLogout)
|
}, msUntilLogout)
|
||||||
|
|
||||||
const msUntilWarning = msUntilLogout - this.sessionWarningLeadMs
|
const msUntilWarning = msUntilLogout - this.sessionWarningLeadMs
|
||||||
@@ -152,12 +152,12 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
// 1. Check: Haben wir überhaupt ein Token?
|
// 1. Check: Haben wir überhaupt ein Token?
|
||||||
const token = useCookie("token").value
|
const token = useCookie("token").value
|
||||||
|
|
||||||
/*if (!token) {
|
if (!token) {
|
||||||
// Kein Token -> Wir sind fertig, User ist Gast.
|
// Kein Token -> Wir sind fertig, User ist Gast.
|
||||||
this.user = null
|
this.user = null
|
||||||
this.loading = false
|
this.loading = false
|
||||||
return
|
return
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// 2. Token existiert -> Versuche User zu laden
|
// 2. Token existiert -> Versuche User zu laden
|
||||||
await this.fetchMe(token)
|
await this.fetchMe(token)
|
||||||
@@ -171,6 +171,8 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
// Hier vorsichtig sein: Nicht navigieren, wenn der User auf eine Deep-Link URL will!
|
// Hier vorsichtig sein: Nicht navigieren, wenn der User auf eine Deep-Link URL will!
|
||||||
// navigateTo("/") <-- Das würde ich hier evtl. sogar weglassen und der Middleware überlassen
|
// navigateTo("/") <-- Das würde ich hier evtl. sogar weglassen und der Middleware überlassen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.loading = false
|
||||||
},
|
},
|
||||||
|
|
||||||
async init(token=null) {
|
async init(token=null) {
|
||||||
@@ -199,6 +201,7 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
|
|
||||||
// 1. WICHTIG: Token sofort ins Cookie schreiben, damit es persistiert wird
|
// 1. WICHTIG: Token sofort ins Cookie schreiben, damit es persistiert wird
|
||||||
this.setToken(token)
|
this.setToken(token)
|
||||||
|
this.sessionExpired = false
|
||||||
|
|
||||||
// 2. User Daten laden
|
// 2. User Daten laden
|
||||||
await this.fetchMe(token)
|
await this.fetchMe(token)
|
||||||
@@ -241,6 +244,18 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
navigateTo("/login")
|
navigateTo("/login")
|
||||||
},
|
},
|
||||||
|
|
||||||
|
expireSession() {
|
||||||
|
console.log("Auth session expired")
|
||||||
|
this.resetState()
|
||||||
|
this.sessionExpired = true
|
||||||
|
this.setToken(null)
|
||||||
|
this.loading = false
|
||||||
|
|
||||||
|
if (process.client) {
|
||||||
|
navigateTo("/login")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
resetState() {
|
resetState() {
|
||||||
this.clearSessionTimers()
|
this.clearSessionTimers()
|
||||||
this.user = null
|
this.user = null
|
||||||
@@ -249,8 +264,10 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
this.activeTenant = null
|
this.activeTenant = null
|
||||||
this.tenants = []
|
this.tenants = []
|
||||||
this.activeTenantData = null
|
this.activeTenantData = null
|
||||||
|
this.sessionExpired = false
|
||||||
this.sessionWarningVisible = false
|
this.sessionWarningVisible = false
|
||||||
this.sessionWarningRemainingSeconds = 0
|
this.sessionWarningRemainingSeconds = 0
|
||||||
|
this.loading = false
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchMe(jwt= null) {
|
async fetchMe(jwt= null) {
|
||||||
@@ -260,6 +277,13 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
// Token aus Argument oder Cookie holen
|
// Token aus Argument oder Cookie holen
|
||||||
const tokenToUse = jwt || useCookie("token").value
|
const tokenToUse = jwt || useCookie("token").value
|
||||||
|
|
||||||
|
if (!tokenToUse) {
|
||||||
|
const wasSessionExpired = this.sessionExpired
|
||||||
|
this.resetState()
|
||||||
|
this.sessionExpired = wasSessionExpired
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const me = await useNuxtApp().$api("/api/me", {
|
const me = await useNuxtApp().$api("/api/me", {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -296,9 +320,12 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
// WICHTIG: Hier NICHT this.logout() aufrufen, weil das navigiert!
|
// WICHTIG: Hier NICHT this.logout() aufrufen, weil das navigiert!
|
||||||
console.log("fetchMe failed (Invalid Token or Network)", err)
|
console.log("fetchMe failed (Invalid Token or Network)", err)
|
||||||
|
|
||||||
// Stattdessen nur den State sauber machen und Token löschen
|
if (err?.response?.status === 401 || err?.status === 401 || err?.statusCode === 401) {
|
||||||
this.resetState()
|
this.expireSession()
|
||||||
this.setToken(null)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = false
|
||||||
|
|
||||||
// Wir werfen den Fehler nicht weiter, damit initStore normal durchläuft
|
// Wir werfen den Fehler nicht weiter, damit initStore normal durchläuft
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user