Add middleware and guards
This commit is contained in:
parent
7b976a0097
commit
14965aa60b
|
|
@ -0,0 +1,49 @@
|
|||
import type {NavigationGuardWithThis, RouteLocationNormalized} from 'vue-router';
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import type {Store} from 'pinia';
|
||||
|
||||
const cookieName = 'loginStatus'
|
||||
let userStore: Store | null = null
|
||||
|
||||
|
||||
|
||||
export const updateLoggedIn: NavigationGuardWithThis<undefined> = (_to) => {
|
||||
const loggedIn = getCookieValue(cookieName) === 'true'
|
||||
const store = getUserStore()
|
||||
|
||||
store.$patch({ loggedIn })
|
||||
}
|
||||
|
||||
export const redirectToLoginIfRequired: NavigationGuardWithThis<undefined> = (to, _from) => {
|
||||
const store = getUserStore()
|
||||
if(loginRequired(to) && !store.loggedIn) {
|
||||
return { name: 'home' }
|
||||
}
|
||||
}
|
||||
|
||||
const getCookieValue = (cookieName: string): string => {
|
||||
// https://stackoverflow.com/questions/5639346/what-is-the-shortest-function-for-reading-a-cookie-by-name-in-javascript
|
||||
const cookieValue = document.cookie.match('(^|[^;]+)\\s*' + cookieName + '\\s*=\\s*([^;]+)')
|
||||
if (!cookieValue) {
|
||||
return ''
|
||||
}
|
||||
return cookieValue.pop() || '';
|
||||
}
|
||||
|
||||
// Pina is not ready when router is called the first time by app.use(), so we need to load it here
|
||||
const getUserStore = (): Store => {
|
||||
if (!userStore) {
|
||||
userStore = useUserStore()
|
||||
}
|
||||
return userStore
|
||||
}
|
||||
|
||||
const loginRequired = (to: RouteLocationNormalized) => {
|
||||
return !to.meta?.public
|
||||
}
|
||||
|
||||
|
||||
|
||||
// export const unauthorizedAccess: NavigationGuardWithThis<undefined> = (to) => {
|
||||
// r loginRequired(to) && getCookieValue('loginStatus') !== 'true';
|
||||
// }
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import HomeView from '../views/HomeView.vue';
|
||||
import learningPathRoutes from './learningpath.routes'
|
||||
import {redirectToLoginIfRequired, updateLoggedIn} from "@/router/guards";
|
||||
|
||||
const loginUrl = '/sso/login/'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
|
|
@ -10,15 +13,19 @@ const router = createRouter({
|
|||
name: 'home',
|
||||
component: HomeView,
|
||||
meta: {
|
||||
layout: 'NoNavbarDemoLayout'
|
||||
layout: 'NoNavbarDemoLayout',
|
||||
public: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
component: HomeView,
|
||||
beforeEnter(to, from, next) {
|
||||
window.location.href = "/sso/login/";
|
||||
beforeEnter(_to, _from) {
|
||||
window.location.href = loginUrl
|
||||
},
|
||||
meta: {
|
||||
public: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
|
|
@ -32,4 +39,7 @@ const router = createRouter({
|
|||
]
|
||||
})
|
||||
|
||||
router.beforeEach(updateLoggedIn)
|
||||
router.beforeEach(redirectToLoginIfRequired)
|
||||
|
||||
export default router
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useCounterStore = defineStore({
|
||||
id: 'counter',
|
||||
state: () => ({
|
||||
counter: 0
|
||||
}),
|
||||
getters: {
|
||||
doubleCount: (state) => state.counter * 2
|
||||
},
|
||||
actions: {
|
||||
increment() {
|
||||
this.counter++
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import { defineStore } from 'pinia'
|
||||
// typed state https://stackoverflow.com/questions/71012513/when-using-pinia-and-typescript-how-do-you-use-an-action-to-set-the-state
|
||||
export const useUserStore = defineStore({
|
||||
id: 'user',
|
||||
state: () => ({
|
||||
email: '',
|
||||
loggedIn: false
|
||||
}),
|
||||
getters: {
|
||||
},
|
||||
actions: {
|
||||
setEmail (email: string) {
|
||||
this.email = email
|
||||
},
|
||||
setLoggedIn (isLoggedIn: boolean) {
|
||||
this.loggedIn = isLoggedIn
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -12,9 +12,9 @@ export default {
|
|||
setup () {
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await getUserData();
|
||||
users.value = res.data;
|
||||
console.log(res);
|
||||
// const res = await getUserData();
|
||||
// users.value = res.data;
|
||||
// console.log(res);
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ MIDDLEWARE = [
|
|||
"django_htmx.middleware.HtmxMiddleware",
|
||||
"vbv_lernwelt.core.middleware.auth.AuthenticationRequiredMiddleware",
|
||||
"vbv_lernwelt.core.middleware.security.SecurityRequestResponseLoggingMiddleware",
|
||||
"vbv_lernwelt.core.middleware.auth.UserLoggedInCookieMiddleWare",
|
||||
]
|
||||
|
||||
# STATIC
|
||||
|
|
|
|||
|
|
@ -45,3 +45,23 @@ class DjangoViewAuthenticationExemptDRFViewSetMixin:
|
|||
)
|
||||
view.authentication_exempt = True
|
||||
return view
|
||||
|
||||
|
||||
# https://stackoverflow.com/questions/4898408/how-to-set-a-login-cookie-in-django
|
||||
class UserLoggedInCookieMiddleWare(MiddlewareMixin):
|
||||
"""
|
||||
Middleware to set user cookie
|
||||
If user is authenticated and there is no cookie, set the cookie,
|
||||
If the user is not authenticated and the cookie remains, delete it
|
||||
"""
|
||||
|
||||
cookie_name = 'loginStatus'
|
||||
|
||||
def process_response(self, request, response):
|
||||
# if user and no cookie, set cookie
|
||||
if request.user.is_authenticated and not request.COOKIES.get(self.cookie_name):
|
||||
response.set_cookie(self.cookie_name, 'true')
|
||||
elif not request.user.is_authenticated and request.COOKIES.get(self.cookie_name):
|
||||
# else if if no user and cookie remove user cookie, logout
|
||||
response.delete_cookie(self.cookie_name)
|
||||
return response
|
||||
|
|
|
|||
Loading…
Reference in New Issue