Controlla se Axios ha un cookie di sessione

Aug 20 2020

Sto implementando una protezione di navigazione per la mia applicazione Vue.js, controllando se l'utente è loggato. Penso che il modo migliore sarebbe chiedere ad Axios se ha un cookie di sessione o meno. Qualcosa come questo:

router.beforeEach((to, from, next) => {
  if (Vue.axios.hasSessionCookie())
    next()
  else
    next(false);
}

Tranne che, ovviamente, hasSessionCookie()non esiste e non vedo niente di simile nei documenti. C'è un modo, forse per estensione?

Sì, so che potrei memorizzare lo stato di accesso nel negozio VueX. Non credo sia una buona idea perché lo stato si ripristinerebbe se l'utente, nella sua infinita saggezza, aggiornasse la pagina e quindi resettasse l'applicazione. Un'altra soluzione che ho in mente è un endpoint di backend in cui l'app può "chiedere" se ha effettuato l'accesso. Ma anche questo è piuttosto noioso.

Risposte

2 TamásPolgár Aug 20 2020 at 06:45

Grazie per tutti i suggerimenti. La soluzione giusta era la seguente:

  • VueX memorizza lo stato di accesso (semplicemente un flag booleano) che la guardia di navigazione controlla
  • Quando l'utente effettua il login o la disconnessione, ho impostato il flag
  • Quando l'app viene avviata, chiamo il /checkloginpercorso sul server prima che venga creata l'istanza di Vue. Questo restituisce semplicemente un codice di stato 200 o 401 a seconda che l'utente disponga o meno di una sessione valida. Quindi ho impostato di conseguenza il flag VueX. In questo modo l'utente può aggiornare il browser ma VueX saprà comunque se ha effettuato l'accesso o meno.
  • Inoltre ho aggiunto un intercettore Axios per rilevare errori 401. Se ce n'è uno, significa che la sessione è scaduta. Quindi imposta il flag VueX su falsee reindirizza l'utente alla pagina di accesso.

Ho scritto un articolo sul mio blog Medium con dettagli e snippet se a qualcuno interessa. https://medium.com/developer-rants/session-management-between-express-and-axios

1 Owl Aug 20 2020 at 03:54

Poiché è un cookie lato server, non è possibile verificarlo su javascript lato client, è necessario effettuare una richiesta HTTP al server Express per verificare se la sessione esiste. Crea un percorso semplice sul tuo server Express come questo:

app.get("/checkcookie", function(req,res) {
    if (req.session.yourSessionVariableName) {
        res.status(204).send();
    } else {
        res.status(401).send();
    }
});

Quindi controlla la tua guardia di navigazione vue:

router.beforeEach(async (to, from, next) => {
  const response = await axios.get("http://yourexpressbackend.com/checkcookie");
  if (response.status === 204)
    next()
  else
    next(false);
}
Akbarkhan Aug 20 2020 at 03:16

Stai andando nella giusta direzione ma axios è un client HTTP e non ha nulla a che fare con i cookie né si preoccupa dei cookie o dell'archiviazione .. quindi devi usare un pacchetto come vue-cookies per impostare e ottenere i cookie.

generic3892372 Nov 01 2020 at 21:47

Tamás Polgár, hai documentato la stessa identica sfida che ho avuto con Vue; cosa fare con l'accesso se si verifica un evento imprevisto del browser e il negozio viene perso.

Il negozio Vue:

Il negozio Vue è pensato per essere una posizione comoda per una SPA per memorizzare tale flag (connesso o meno), tuttavia, il negozio viene completamente cancellato e ristabilito con ogni istanza di Vue, il che significa una nuova finestra / scheda del browser, aggiornamento o un altro evento imprevisto che attiva un aggiornamento del browser.

Quindi il tuo approccio descrive una chiamata di back-end extra per controllare rapidamente lo stato, che è una soluzione legittima e funzionante IMO.

Ci sono anche altre due potenziali soluzioni, la seconda delle quali ho implementato nella mia SPA:

Altre due soluzioni

1) Non toccare affatto il codice del back-end. Utilizzare vue-cookies per fare in modo che il browser del client imposti un cookie una volta stabilito un accesso (questo sarebbe completamente separato dal cookie solo http di cui ha bisogno il server API back-end).

Questo cookie dovrebbe ancora esistere dopo un aggiornamento del browser. Non ho usato (o provato) questo approccio, tuttavia, poiché non volevo scherzare alterando il mio front-end per controllare un cookie locale ogni volta che voglio controllare lo stato di accesso.

Il codice del front-end potrebbe utilizzare questo cookie per capire se la persona è ancora loggata o meno.

2) Un altro approccio separato consiste nel cortocircuitare il normale controllo API back-end per l'autenticazione solo per il controller di quella specifica rotta , ma non per qualsiasi altra rotta.

Ecco come funzionerebbe un "cortocircuito" sul back-end:

Nel caso del metodo del controller di quella rotta specifica, chiedi prima di controllare l'esistenza dell'utente nella richiesta, quindi restituire un 200 ma con uno stato di "false" o qualche altra variabile che appare anche nella risposta di successo.

È controintuitivo, ma questo dà alla chiamata Axios front-end qualcosa a cui aggrapparsi oltre a una semplice risposta di errore standard.

NOTA : lo chiamo un "cortocircuito" perché se il metodo del controller della route API back-end ha molto codice, rendere questo controllo la PRIMA cosa che fa eviterà la parte costosa della chiamata.

Questo approccio funziona perfettamente per le mie esigenze e non richiede una chiamata API nuova o secondaria.