2014-07-09 10 views
5

Sto cercando di capire il modo giusto per gestire le autorizzazioni in un'applicazione singola pagina che parla direttamente con diverse API RESTful, che implementano HATEOAS.Autorizzazioni su un resto API che implementa HATEOAS

Per fare un esempio:

"In qualità di utente della mia applicazione posso visualizzare, avviare e mettere in pausa i lavori, ma non fermarli."

Il resto API sottostante ha la seguente risorsa:

/lavori/{id} che accetta GET e PUT. Il GET restituisce un modello di lavoro e il PUT accetta un modello di lavoro come corpo della richiesta in forma:

{ 
"_links" : { 
    "self" : "/jobs/12345678" 
} 
"id" : 12345678, 
"description" : "foo job", 
"state" : "STOPPED" 
} 

accettate stati di lavoro possono essere: dormiente | correndo | in pausa | fermato.

Il requisito dice che sulla UI devo avere i tasti:

START, Pause, Stop

... e solo visualizzare in base alla loggato permessi dell'utente.

Dal punto di vista dell'API, tutto funziona come logica sottostante sul server, per garantire che l'utente non possa aggiornare lo stato a uno stato STOPPED quando viene effettuata una richiesta (è possibile che venga restituito un 401).

Qual è il modo migliore per informare l'app/l'interfaccia utente delle autorizzazioni dell'utente, in modo che possa nascondere tutti i pulsanti che l'utente non ha il permesso di agire?

caso l'API di fornire un elenco di autorizzazioni, forse qualcosa di simile:

{ 
"_links" : { 
    "self" : "/permissions", 
    "jobs" : "/jobs" 
} 
"permissions" : { 
    "job" : ["UPDATE", "DELETE"], 
    "job-updates" : ["START", "PAUSE"] 
    } 
} 

o dovrebbe il cambiamento API in modo che le autorizzazioni siano riflessi nei collegamenti HATEOS Forse qualcosa di simile:

{ 
"_links" : { 
    "self" : "/jobs/12345678", 
    "start" : "/jobs/12345678/state?to=RUNNING", 
    "pause" : "/jobs/12345678/state?to=PAUSED", 
} 
"id" : 12345678, 
"description" : "foo job", 
"state" : "DORMANT" 
} 

O dovrebbe essere fatto in un modo completamente diverso?

UPDATE

ho trovato il seguente articolo che suggerisce una risposta: https://softwareengineering.stackexchange.com/questions/215975/how-to-handle-fine-grained-field-based-acl-permissions-in-a-restful-service

risposta

5

vorrei andare con quest'ultimo: Implicano le autorizzazioni in base alle quali i collegamenti sono presenti.

Se il collegamento non è presente, l'utente non può accedere alla risorsa/eseguire l'azione. Se lo è, possono farlo. Questo è quello che farei, perché è semplice e pulito e lascia poco alla discrezione del codice di front-end. Disaccoppiamento, yo.

In alternativa, se si fa voler includere tutti i collegamenti in ogni risposta, ma esplicitamente specificare quali sono permesse e quali no, se si utilizza un formato come HAL di scrivere il vostro link, si potrebbe estenderlo con un flag su ogni collegamento in questo modo:

{ 
    "_links" : { 
     "self" : { 
      "href":"/jobs/12345678", 
      "allowed":false 
     }, 
     "start" : { 
      "href":"/jobs/12345678/state?to=RUNNING", 
      "allowed":false 
     }, 
     "pause" : { 
      "href":"/jobs/12345678/state?to=PAUSED", 
      "allowed":false 
     } 
    }, 
    "id" : 12345678, 
    "description" : "foo job", 
    "state" : "DORMANT" 
} 
+0

non è un fan della bandiera, ma è in disaccordo con la risposta. Fornire collegamenti per indicare le azioni disponibili è uno dei principali vantaggi di HATEOAS. Proprio come su una pagina web, non c'è nessun pulsante di cancellazione se non riesco a cancellare una voce –

+0

neanche io sono un fan della bandiera. Penso che nella maggior parte dei casi, la bandiera non sia appropriata, ma posso capire perché in alcuni casi potrebbe essere possibile. A volte un'azione non è possibile a causa di uno stato di elaborazione, ad esempio. Tuttavia, ci sono altri modi per indicare questo tipo di cose includendo il collegamento (come un attributo nel corpo) e restituendo il codice di stato appropriato a qualsiasi richiesta se il collegamento viene effettivamente utilizzato. – basicallydan

1

Vorrei andare con quest'ultimo.Il motivo per cui non mi piace il primo è che si sta creando un lavoro extra per il client richiedendolo per capire la mappatura tra le autorizzazioni e le risorse a cui consentire l'accesso. Se usi gli hateo e controlli la presenza di tipi di relazione, questa mappatura è fatta per te dal server. Significa anche che l'uris può cambiare senza rompere il client.

Recentemente ho scritto un post su questo settore:

https://www.opencredo.com/2015/08/12/designing-rest-api-fine-grained-resources-hateoas-hal/

+0

Come si definisce in tale approccio l'operazione consentita, ad es. PUT etc? – Dejell

0

Si deve usare forme, non link, per fornire stato di transizione ipermedia. Se non è possibile fornire moduli nel proprio tipo di supporto, fornire collegamenti a URI che utilizzano un altro tipo di supporto che supporti moduli, come XHTML.

IANA ha link relations per create-form, edit-form e delete-form per questo scopo.

Inoltre, si prega di non utilizzare start e pause come relazioni di collegamento reali. Se li definisci tu stesso, devono essere URI (preferibilmente URL HTTP, ma qualsiasi URI sotto il tuo controllo sarà sufficiente). start ha un significato completamente diverso da quello per cui lo stai utilizzando, e pause non è definito.

Problemi correlati