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