Axios request failed with status code 403

Salutare, vreau sa fac o aplicatie magazin online iar atunci cand vreau sa plasez o comanda sa o afisez in partea de istoric a aplicatiei, imi apare o eroare: AxiosError: Request failed with status code 403. Am reverificat jwt, axios, fetch data cu useeffect, dar tot nu-mi dau seama de ce nu merge. Initial cand am creat functionalitatea aplicatiei mergea placeorder action, dupa ce am schimbat

const authorization = req.headers.authorization

cu

const authorization = req.headers['authorization']

in functia isAuth din utils.js ; Am tot cautat peste tot pe netul asta si nu reusesc deloc sa o rezolv. Aici este link-ul cu intregul proiect, poate e in alta parte a aplicatiei eroarea: https://github.com/burNN11/newProject



Dacă pui pe server

console.log(req.headers.authorization)

Ce spune serverul cand e accesată resursa respectivă?

Bearer [object Object]
log

Testeaza backend-ul cu postman si cu token, e mai simplu.

La front-end e o problema, nu folosesti un wrapper/ o fatada pentru instanta de axios, trebuie sa faci o instanta de axios (un serviciu sau provider) si o configuratie pentru axios cu care creezi instanta.

Pui un interceptor in configuratie la instanta de axios in care setezi config.headers.Authorization pe request cu token-ul din context/localStorage sub forma

axios.interceptors.request.use((config) => {
   config.headers.Authorization = `Bearer ${token}`;
   return Promise.resolve(config);
}

Am vazut ca folosesti

 const fetchOrder = async () => {
      try {
        dispatch({ type: 'FETCH_REQUEST' });
        const { data } = await Axios.get(`/api/orders/${orderId}`, {
          headers: { authorization: `Bearer ${userInfo.token}` },
        });
        dispatch({ type: 'FETCH_SUCCESS', payload: data });
      } catch (err) {
        alert(err);
      }
    };

ceea ce totusi ar trebui sa functioneze.

Nu folosi useEffect pentru a lua date, foloseste react query.
React Query - Hooks for fetching, caching and updating asynchronous data in React (tanstack.com)

[object Object] este varianta stringified a { token: { expiresIn: "15d" } } si nu e ceea ce ar trebui sa primeasca back-endul pentru headerul de authorization ci un string cu un token.

Doar mie mi se pare o problema de securitate stocarea tokenului de authentificare in local storage?

Nu exista nici un motiv pentru care ar fi o problema daca ai o aplicatie bine scrisa care n-are XSS. React nu permite XSS daca nu folosesti dangerouslySetInnerHTML sau nu folosesti o librarie care face asta.

Daca poti face XSS poti face orice doresti oricum (bine de obicei e o limita a numarului de caractere si trebuie sa fii foarte creativ), indiferent de ce metoda ai folosi.

In locurile unde conteaza la fiecare operatie care necesita permisiuni mai elevate invalidezi token-ul oricum daca e mai vechi de 5-10 minute ca utilizatorul sa primeasca un token nou si il duci inapoi la pagina de dinainte.

How about httponly cookie?

Poti seta un cookie doar daca nu chemi 20 de microservicii diferite din front-end.

Depinde de arhitectura. Dar este foarte posibil si usor de implementat. Adica daca ai 20 de micro servicii, banuiesc ca ai si unul pentru session management.

Filozofia mea e ca daca ai XSS e game over orice ai face, nu fura token-ul (care oricum expira la cateva ore) ci poate sa faca aplicatia sa faca ceva nedorit de cineva rau intentionat.

Ai rezolvat o problema evidenta fiindca e mai usor de utilizat direct, dar n-ai rezolvat problema.

Daca imi dai un XSS pe devforum eu iti afisez lejer pagina de login care imi trimite parola ta intr-un spreadsheet.

Paginile mai complexe (Google Sheets/Office 365…) folosesc iframe-uri cu subdomenii dinamice pentru a izola functiile care sunt mai vulnerabile (scripturi third party) si inclusiv JS-ul e rulat doar pe backend si randarea se face prin fatade (API).

sau in ci/cd cu inso :innocent: Inso, the Insomnia CLI tool for CI/CD API Pipelines - Insomnia

1 Like

Patternul backend-for-frontend e fosrte util. Sa expui intreaga paleta de microservicii pt a fi accesibila din orice client browser e periculos, to say the least.

De obicei ai un gateway, dar gatewayul ar trebui sa fie stateless altfel nu il poti scala/distribui usor fara o baza de date pentru sesiuni si ai dat o palma toata infrastructurii netflix/de microservicii. Practic puteai sa faci un monolit sau devine mult mai complex si scump sa il faci bine. Backend for front-end e tot un microserviciu care trece prin gateway.

Plus o baza de date de sesiuni e visul oricarui care face ddos, inseamna ca poti pune pe butuci orice server incarcand baza de date cu sesiunile, fie el redis sau altceva in memorie,. Daca folosesti postgres/mysql pentru sesiuni esti mort la cel mai simplu ddos.