Login bei abgelaufener Sitzung korrigieren

This commit is contained in:
2026-05-26 16:27:08 +02:00
parent cb09651d8d
commit f002ad867a
3 changed files with 51 additions and 11 deletions

View File

@@ -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

View File

@@ -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"

View File

@@ -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
}