Refactor auth middleware and add logout functionality

Since there are multiple significant changes, a message body is
warranted:

- Replace token refresh logic with simple route protection - Move cookie
deletion to new system store - Add logout button and handler to index
page - Rename Chuck Norris store for consistency
This commit is contained in:
2025-08-11 15:22:39 +02:00
parent 65e0c583cf
commit b607380a68
5 changed files with 47 additions and 33 deletions

View File

@@ -1,29 +1,15 @@
import { fa } from "vuetify/locale";
// file: ~/middleware/authentication.global.ts
export default defineNuxtRouteMiddleware(async (to) => {
const { status, refresh } = useAuth();
const deleteCookies = () => {
const atoken = useCookie("authls.atoken");
atoken.value = null;
const rtoken = useCookie("authls.rtoken");
rtoken.value = null;
};
// Return immediately if user is already authenticated and protected page
if (status.value === "authenticated" && to.meta.auth === true) {
console.log("case 1");
return;
export default defineNuxtRouteMiddleware(async (to, next) => {
const { status } = useAuth();
const auth = status.value === "authenticated" ? true : false;
const isProtected = (await to.meta.auth) === true ? true : false;
if (!auth && isProtected) {
console.log("User is not authenticated and page is protected");
return navigateTo("/login");
} else if (auth && !isProtected) {
console.log("User is authenticated and page is not protected");
return navigateTo("/");
}
if (status.value !== "authenticated" && to.meta.auth === true) {
try {
console.log("case 2");
await refresh();
} catch {
console.log("case 3");
deleteCookies();
}
return;
}
deleteCookies();
return;
});

View File

@@ -12,10 +12,14 @@
{{ norrisStore.response }}
{{ data }}
{{ status }}
{{ refreshToken }}
</div>
<div>
<v-btn color="primary" @click="refresh">Refresca token</v-btn>
</div>
<div>
<v-btn color="warning" @click="logout">Logout</v-btn>
</div>
</v-container>
</template>
@@ -24,9 +28,16 @@ definePageMeta({
auth: true,
});
import { ref, onMounted } from "vue";
import { useChuckNorris } from "~/stores/chuck";
const norrisStore = useChuckNorris();
const { data, status, refresh } = useAuth();
import { useChuckStore } from "~/stores/chuck";
import { useSystemStore } from "~/stores/system";
const systemStore = useSystemStore();
const norrisStore = useChuckStore();
const { data, status, refresh, refreshToken, signOut } = useAuth();
const logout = async () => {
await systemStore.deleteCookies();
await signOut({ callbackUrl: "/login" });
};
onMounted(async () => {
await norrisStore.getData();

View File

@@ -1,6 +1,6 @@
import { defineStore } from "pinia";
export const useChuckNorris = defineStore("chuckNorris", {
export const useChuckStore = defineStore("chuckNorris", {
state: () => ({
response: "",
}),

17
app/stores/system.js Normal file
View File

@@ -0,0 +1,17 @@
import { defineStore } from "pinia";
export const useSystemStore = defineStore("system", {
state: () => ({
url: "localhost:3000",
url_backend: "localhost:8000",
}),
actions: {
async deleteCookies() {
console.log("Logout clicked in store");
const atoken = useCookie("authls.atoken");
atoken.value = null;
const rtoken = useCookie("authls.rtoken");
rtoken.value = null;
},
},
});

View File

@@ -8,7 +8,7 @@ export default defineNuxtConfig({
baseURL: "http://localhost:3000",
},
auth: {
globalAppMiddleware: true,
globalAppMiddleware: false,
baseURL: "http://localhost:8000/auth",
provider: {
type: "local",
@@ -17,7 +17,7 @@ export default defineNuxtConfig({
type: "JWT",
headerName: "Authorization",
cookieName: "authls.atoken",
maxAgeInSeconds: 30 * 60,
maxAgeInSeconds: 30 * 59,
},
refresh: {
isEnabled: true,
@@ -28,7 +28,7 @@ export default defineNuxtConfig({
refreshResponseTokenPointer: "/access",
refreshRequestTokenPointer: "/refresh",
cookieName: "authls.rtoken",
maxAgeInSeconds: 60 * 60 * 24,
maxAgeInSeconds: 60 * 60 * 23, // En 23 horas refresca automáticamente
sameSiteAttribute: "strict",
},
},