Identity and Authentication
This document describes the current frontend authentication and identity flow.
Overview
- Authentication is session-based. A valid
sessionidcookie indicates an authenticated session. - Login is handled via
POST /account/login/and sets the session cookie. - User identity, groups, and permissions are hydrated from
GET /account/me/. - The app uses a
userPinia store for identity and permission checks. - The app uses
app.loginRequiredto toggle the login overlay.
Backend endpoints
POST /account/login/- Response includes:
user(string)user_detail(object with basic user fields)groups(array of Django groups)permissions(array of permission strings)
- Response includes:
GET /account/me/- Requires authentication.
- Response includes:
user(user id)user_detail(object with basic user fields)groups(array of Django groups)permissions(array of permission strings)
POST /account/logout/- Logs out the current session.
Frontend flow
Login
- The login overlay is shown when
app.loginRequiredistrue. Login.vueposts credentials to/account/login/.- On success, it populates the
userstore from the response and reloads the page.
Session detection
Default.vuewatches thesessionidcookie.- If the cookie is missing:
app.loginRequiredis set totrueuserStore.clear()is called
- If the cookie is present:
app.loginRequiredis set tofalseuserStore.hydrate()calls/account/me/to refresh identity data
Request handling
useHttp.sendRequestsetsapp.loginRequired = truewhen a request returns403with"Authentication credentials were not provided.".
Stores
user store (src/store/user.js)
State:
user: user detail object fromuser_detailgroups: group listpermissions: permission listloading: request state for hydration
Actions:
hydrate(): loads user data from/account/me/setFromResponse(payload): setsuser,groups,permissionsfrom the login/me responseclear(): resets identity data
Getters:
isAuthenticated: true whenuser.idexistshasPermission(permission): checks permission stringhasRole(roleName): checks group name
Examples
js
import { computed, onMounted } from 'vue'
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
const userData = computed(() => userStore.user)
const isAuthed = computed(() => userStore.isAuthenticated)
const canViewInvoices = computed(() => userStore.hasPermission('project.view_invoice'))
const isAdmin = computed(() => userStore.hasRole('Admin'))
onMounted(() => {
userStore.hydrate()
})app store (src/store/app.js)
State:
loginRequired: controls login overlay visibility
Router guard behavior
- A global
beforeEachchecks for asessionidcookie. - If missing, it marks
loginRequiredand clears user data. - Navigation is not blocked; the login overlay is used instead.
Notes
- The login flow is session-cookie based and does not use tokens.