2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00

refactor(frontend): Do not request token in frontend (#9217)

* remove calls that reference tokens

* remove call to token endpoint

* ensure CSRFToken is always send

* bump axios

* lower axios

* reset axios change

* bump reslution down
This commit is contained in:
Matthias Mair 2025-03-15 22:36:58 +01:00 committed by GitHub
parent 0e43e8de2d
commit 516755db97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 34 deletions

View File

@ -2,7 +2,6 @@ import { QueryClient } from '@tanstack/react-query';
import axios from 'axios'; import axios from 'axios';
import { useLocalState } from './states/LocalState'; import { useLocalState } from './states/LocalState';
import { useUserState } from './states/UserState';
// Global API instance // Global API instance
export const api = axios.create({}); export const api = axios.create({});
@ -12,7 +11,6 @@ export const api = axios.create({});
*/ */
export function setApiDefaults() { export function setApiDefaults() {
const { host } = useLocalState.getState(); const { host } = useLocalState.getState();
const { token } = useUserState.getState();
api.defaults.baseURL = host; api.defaults.baseURL = host;
api.defaults.timeout = 5000; api.defaults.timeout = 5000;
@ -22,11 +20,10 @@ export function setApiDefaults() {
api.defaults.xsrfCookieName = 'csrftoken'; api.defaults.xsrfCookieName = 'csrftoken';
api.defaults.xsrfHeaderName = 'X-CSRFToken'; api.defaults.xsrfHeaderName = 'X-CSRFToken';
if (token) { axios.defaults.withCredentials = true;
api.defaults.headers.Authorization = `Token ${token}`; axios.defaults.withXSRFToken = true;
} else { axios.defaults.xsrfHeaderName = 'X-CSRFToken';
delete api.defaults.headers['Authorization']; axios.defaults.xsrfCookieName = 'csrftoken';
}
} }
export const queryClient = new QueryClient({ export const queryClient = new QueryClient({

View File

@ -66,7 +66,8 @@ export const doBasicLogin = async (
navigate: NavigateFunction navigate: NavigateFunction
) => { ) => {
const { host } = useLocalState.getState(); const { host } = useLocalState.getState();
const { clearUserState, setToken, fetchUserState } = useUserState.getState(); const { clearUserState, setAuthenticated, fetchUserState } =
useUserState.getState();
const { setAuthContext } = useServerApiState.getState(); const { setAuthContext } = useServerApiState.getState();
if (username.length == 0 || password.length == 0) { if (username.length == 0 || password.length == 0) {
@ -94,7 +95,7 @@ export const doBasicLogin = async (
.then((response) => { .then((response) => {
setAuthContext(response.data?.data); setAuthContext(response.data?.data);
if (response.status == 200 && response.data?.meta?.is_authenticated) { if (response.status == 200 && response.data?.meta?.is_authenticated) {
setToken(response.data.meta.access_token); setAuthenticated(true);
loginDone = true; loginDone = true;
success = true; success = true;
} }
@ -217,7 +218,7 @@ function observeProfile() {
export async function ensureCsrf() { export async function ensureCsrf() {
const cookie = getCsrfCookie(); const cookie = getCsrfCookie();
if (cookie == undefined) { if (cookie == undefined) {
await api.get(apiUrl(ApiEndpoints.user_token)).catch(() => {}); await api.get(apiUrl(ApiEndpoints.auth_session)).catch(() => {});
} }
} }
@ -251,7 +252,7 @@ export function handleMfaLogin(
values: { code: string }, values: { code: string },
setError: (message: string | undefined) => void setError: (message: string | undefined) => void
) { ) {
const { setToken, fetchUserState } = useUserState.getState(); const { setAuthenticated, fetchUserState } = useUserState.getState();
const { setAuthContext } = useServerApiState.getState(); const { setAuthContext } = useServerApiState.getState();
authApi(apiUrl(ApiEndpoints.auth_login_2fa), undefined, 'post', { authApi(apiUrl(ApiEndpoints.auth_login_2fa), undefined, 'post', {
@ -260,7 +261,7 @@ export function handleMfaLogin(
.then((response) => { .then((response) => {
setError(undefined); setError(undefined);
setAuthContext(response.data?.data); setAuthContext(response.data?.data);
setToken(response.data.meta.access_token); setAuthenticated();
fetchUserState().finally(() => { fetchUserState().finally(() => {
observeProfile(); observeProfile();

View File

@ -10,14 +10,13 @@ import type { UserProps } from './states';
export interface UserStateProps { export interface UserStateProps {
user: UserProps | undefined; user: UserProps | undefined;
token: string | undefined; is_authed: boolean;
userId: () => number | undefined; userId: () => number | undefined;
username: () => string; username: () => string;
setAuthenticated: (authed?: boolean) => void;
fetchUserToken: () => Promise<void>;
setUser: (newUser: UserProps | undefined) => void; setUser: (newUser: UserProps | undefined) => void;
getUser: () => UserProps | undefined; getUser: () => UserProps | undefined;
setToken: (newToken: string | undefined) => void;
clearToken: () => void;
fetchUserToken: () => void;
fetchUserState: () => Promise<void>; fetchUserState: () => Promise<void>;
clearUserState: () => void; clearUserState: () => void;
checkUserRole: (role: UserRoles, permission: UserPermissions) => boolean; checkUserRole: (role: UserRoles, permission: UserPermissions) => boolean;
@ -33,6 +32,7 @@ export interface UserStateProps {
hasChangePermission: (model: ModelType) => boolean; hasChangePermission: (model: ModelType) => boolean;
hasAddPermission: (model: ModelType) => boolean; hasAddPermission: (model: ModelType) => boolean;
hasViewPermission: (model: ModelType) => boolean; hasViewPermission: (model: ModelType) => boolean;
isAuthed: () => boolean;
isLoggedIn: () => boolean; isLoggedIn: () => boolean;
isStaff: () => boolean; isStaff: () => boolean;
isSuperuser: () => boolean; isSuperuser: () => boolean;
@ -43,13 +43,9 @@ export interface UserStateProps {
*/ */
export const useUserState = create<UserStateProps>((set, get) => ({ export const useUserState = create<UserStateProps>((set, get) => ({
user: undefined, user: undefined,
token: undefined, is_authed: false,
setToken: (newToken: string | undefined) => { setAuthenticated: (authed = true) => {
set({ token: newToken }); set({ is_authed: authed });
setApiDefaults();
},
clearToken: () => {
get().setToken(undefined);
setApiDefaults(); setApiDefaults();
}, },
userId: () => { userId: () => {
@ -68,8 +64,7 @@ export const useUserState = create<UserStateProps>((set, get) => ({
setUser: (newUser: UserProps | undefined) => set({ user: newUser }), setUser: (newUser: UserProps | undefined) => set({ user: newUser }),
getUser: () => get().user, getUser: () => get().user,
clearUserState: () => { clearUserState: () => {
get().setUser(undefined); set({ user: undefined, is_authed: false });
get().setToken(undefined);
clearCsrfCookie(); clearCsrfCookie();
setApiDefaults(); setApiDefaults();
}, },
@ -79,30 +74,30 @@ export const useUserState = create<UserStateProps>((set, get) => ({
!document.cookie.includes('csrftoken') && !document.cookie.includes('csrftoken') &&
!document.cookie.includes('sessionid') !document.cookie.includes('sessionid')
) { ) {
get().clearToken(); get().setAuthenticated(false);
return; return;
} }
await api await api
.get(apiUrl(ApiEndpoints.user_token)) .get(apiUrl(ApiEndpoints.auth_session))
.then((response) => { .then((response) => {
if (response.status == 200 && response.data.token) { if (response.status == 200 && response.data.meta.is_authenticated) {
get().setToken(response.data.token); get().setAuthenticated(true);
} else { } else {
get().clearToken(); get().setAuthenticated(false);
} }
}) })
.catch(() => { .catch(() => {
get().clearToken(); get().setAuthenticated(false);
}); });
}, },
fetchUserState: async () => { fetchUserState: async () => {
if (!get().token) { if (!get().isAuthed()) {
await get().fetchUserToken(); await get().fetchUserToken();
} }
// If we still don't have a token, clear the user state and return // If we still don't have a token, clear the user state and return
if (!get().token) { if (!get().isAuthed()) {
get().clearUserState(); get().clearUserState();
return; return;
} }
@ -161,8 +156,11 @@ export const useUserState = create<UserStateProps>((set, get) => ({
get().clearUserState(); get().clearUserState();
}); });
}, },
isAuthed: () => {
return get().is_authed;
},
isLoggedIn: () => { isLoggedIn: () => {
if (!get().token) { if (!get().isAuthed()) {
return false; return false;
} }
const user: UserProps = get().user as UserProps; const user: UserProps = get().user as UserProps;