Cosa c'è di sbagliato nel trattare una sessione client come uno stato di risorsa / applicazione nell'architettura REST?

1

Considerate queste applicazioni REST API / HATEOAS:

  1. InfoQ Come ottenere un esempio di tazza di caffè
  2. Esempio di API REST Java Spring

... dove le risorse POST / PUT / PATCHING alterano chiaramente lo stato / disponibilità di (altre) risorse - ad esempio in:

  1. (REST example API 1)

    PUT /order/1234 HTTP/1.1
    ...
    
    <order>
    ...
      <status>preparing</status>
    ...
    </order>
    

    ... altera lo stato dell'ordine, in modo tale che alcune opzioni di ordine non siano più disponibili;

  2. (REST example API 2)

    PUT /games/1/doors/3 HTTP/1.1
    ...
    
    {"status": "OPEN"}
    

    ... altera lo stato del gioco, in modo tale che alcune opzioni di gioco non sono più disponibili

- cosa sarebbe sbagliato trattando una sessione client come uno stato di risorsa / di un'applicazione?

Considera questo esempio, per vedere cosa intendo:

Let's imagine API key 1234 is the owner of /products/1 and only this API key is allowed to operate on/view this product.

Richiesta:

GET /products/1 HTTP/1.1

Risposta:

HTTP/1.1 403 Forbidden

Richiesta:

POST /sessions HTTP/1.1
Authorization: NiceAPI apikey=1234

<session>
  <apiKey>1234</apiKey>
</session>

Risposta:

HTTP/1.1 201 Created
Location: /sessions/2ef4c...

// created session sent along for convenience
<session>
  <hash>2ef4c...</hash>
  <apiKey>1234</apiKey>
</session>

In risposta a commento di Richard Tingle , la risposta sopra potrebbe essere regolata per inviare un cookie, invece dell'hash nella rappresentazione della risorsa della sessione:

HTTP/1.1 201 Created
Set-Cookie: session=2ef4c...; Secure; HttpOnly
Location: /sessions/2ef4c...

<session>
  <hash>2ef4c...</hash> // not necessary/desirable anymore
  <apiKey>1234</apiKey>
</session>

... per associare la risorsa di sessione a un client

Richiesta:

GET /products/1 HTTP/1.1
X-Session: 2ef4c... // or a Cookie header, etc.

Risposta: (se esiste una risorsa di sessione verificata dal server)

HTTP/1.1 200 OK
// product content

Richiesta:

DELETE /sessions/2ef4c... HTTP/1.1
Authorization: NiceAPI apikey=1234

Risposta: (se la sessione verificata dal server apparteneva alla chiave API)

HTTP/1.1 204 No Content
// session resource successfully deleted

Richiesta:

GET /products/1 HTTP/1.1

Risposta:

HTTP/1.1 403 Forbidden

Voglio dire, in entrambe le applicazioni REST API / HATEOAS menzionate in precedenza le operazioni valide per qualsiasi particolare risorsa dipendevano anche da altri stati di risorsa e / o azioni client precedenti (ad esempio è parte della logica dell'applicazione).

Dato che la gestione dello stato del client / sessione è generalmente disapprovata quando si parla di REST, in che modo le API REST / HATEOAS citate in precedenza dichiarano diversamente dalla mia sessione proposta come stato di risorsa / applicazione?

    
posta Decent Dabbler 03.06.2016 - 17:42
fonte

3 risposte

2

what would be wrong with treating a client session as a resource/an application state as well?

Non c'è niente di sbagliato in questo, il problema si presenta quando si tenta di utilizzare lo stato dell'applicazione (sotto forma di risorse di sessione) come forma di autenticazione.

In pratica stai dicendo che se l'applicazione si trova in questo stato specifico, questo client (ad esempio il client X) viene autenticato per accedere a questa risorsa. Hai trasformato il tuo stato delle risorse in un sistema di autenticazione.

Roy Fielding elenca le ragioni per non farlo.

link

  • La parte di autenticazione del sistema non deve essere a conoscenza dello stato dell'applicazione corrente per autenticare una richiesta. Potresti autenticare una richiesta su un server completamente diverso, oppure la stessa autenticazione potrebbe essere utilizzata in diverse parti del sistema senza dover conoscere lo stato della risorsa.

  • Il sistema è più affidabile. Immagina che l'aggiornamento alla risorsa di sessione non sia riuscito per qualche motivo o che sia stato aggiornato da qualcos'altro dopo che il client ha ricevuto una chiave di sessione. L'utente ha effettuato l'accesso? Quando il client tenta di aggiornare la risorsa prodotti, il server lo rifiuta, ma il client non sa perché. Deve ricordare che in precedenza ha provato ad accedere tramite una sessione, tornare indietro e riprovare. Quindi deve capire da quella risorsa perché non può ottenere una sessione. Chiunque abbia usato un sito web che usa le sessioni può testimoniare quanto diventa confuso, improvvisamente una richiesta può fallire e il sito ti riporta alla pagina di accesso, anche se non c'era nulla di sbagliato nella richiesta. Immagina ora di cercare di analizzare ciò che è successo automaticamente via codice.

  • Il sistema si adatta meglio. Senza che l'applicazione debba tenere traccia delle risorse in relazione tra loro, consente al sistema di scalare. Sì, l'aggiornamento di una risorsa potrebbe avere effetti collaterali (se elimini questa risorsa, cancelli anche questa risorsa), ma quelli sono specifici per la logica del dominio. Non è qualcosa di simile se creo questa risorsa di sessione di raccontare OGNI di queste risorse che per i prossimi 10 minuti questo utente può accedervi. Questo è molto più lo stato dell'applicazione da ricordare e limita enormemente la scalabilità e il caching.

Come molti vantaggi di REST, questi benefici diventano evidenti solo su una scala più ampia di un client che parla con un server web. Scala al di là di questo e sarai molto rapidamente maledire le sessioni.

    
risposta data 06.06.2016 - 13:56
fonte
2

what would be wrong with treating a client session as a resource/an application state as well?

La risposta breve è che si ottengono effetti collaterali imprevisti quando la comprensione da parte del client dello stato dell'applicazione e della comprensione dell'applicazione da parte del server non corrispondono.

Rivedi Fielding: Sezione 6.3.4.2 .

Nota che, negli esempi che descrivi, il protocollo sta cambiando lo stato della risorsa , non lo stato dell'applicazione .

Risposta più lunga.

C'è una discussione molto buona sullo stato dell'applicazione sullo stack overflow: link

Chiarimenti:

Application logic is needed to evaluate the content of the resource to determine what further adjustments (if any) are allowed to be made to the order.

No; La logica dominio è necessaria per valutare se la modifica proposta dal messaggio dal client deve essere consentita.

Fielding (2008)

Don’t confuse application state (the state of the user’s application of computing to a given task) with resource state (the state of the world as exposed by a given service). They are not the same thing.

If REST / HATEOAS would only be about changing resource state (which HATEOAS certainly shouldn't, given the AS part of the acronym) then wouldn't they simply be glorified CRUD data warehouse architectures, without any business logic

Non sono abbastanza sicuro di dove stai andando con quella domanda, ma suppongo che potresti usare una dose di Jim Webber

HTTP is an application protocol... but it's not your application protocol.

Questo potrebbe essere d'aiuto per le tue preoccupazioni su CRUD.

    
risposta data 04.06.2016 - 03:20
fonte
1

Le sessioni sono dati temporanei necessari a un'applicazione e sono in genere ortogonali a ciò che sta facendo l'API. L'aggiunta della gestione delle sessioni nell'API distrae dalle funzionalità principali e potrebbe introdurre bug non pertinenti.

Il posto migliore per i dati di sessione è nell'applicazione stessa. Tuttavia, non c'è nulla da dire che non è possibile creare un'API separata per gestire i dati della sessione.

Un esempio simile è quando si utilizza un servizio token (OAuth / Open ID Connect) per l'autenticazione (autenticazione e autorizzazione). Queste cose sono facili da sbagliare. La gestione di questi nella tua API non è l'ideale quando i prodotti esistono per farlo per te. Pertanto, la tua API fa ciò che sa e rimanda le domande sulle risorse che non gestisce per l'API proprietaria.

    
risposta data 03.06.2016 - 21:24
fonte

Leggi altre domande sui tag