Are there any best practices for exposing resource permissions/ACL to a front end via a RESTful API?

StackOverflow https://stackoverflow.com/questions/19484227

Вопрос

The question pretty much covers it. Given a RESTful API where we have multiple resource types and various user permissions around who can CRUD them, are there any established best practices for exposing those permissions to the front end so that the permissions don't have to be stored in two places?

I have a pure JS application and I need to know when to, for example, display edit and delete links for a given resource. I would like a standard way to make these decisions based directly on the ACLs stored on the backend. I considered maybe bringing back an ACL portion in the REST envelope for all GET responses, but I was hoping maybe someone knew of an established best practice.

For what it's worth, I'm also using Symfony2 and its security component.

Это было полезно?

Решение

In a purely RESTful scenario, the client wouldn't manage an ACL at all. Rather, as the client requests information, returned resources would include links from those resources to possible links the client could follow. That way the server is telling the client what can and cannot be done with the given resource (specific to who is requesting it).

Example: your JS client retrieves a JSON payload for an item which has been purchased but has not yet been shipped. The client might receive a payload that looks like this:

{
  "name": "Gadget 1",
  "price": "16.99",
  "status": "ORDERED",
  "_links": {
    "details": { "href": "/item/a631723d69/details",
                 "method": "GET"),
    "cancel-shipment": {  "href": "/item/a631723d69",
                 "method": "DELETE" }
  }
}

Because the server returned the cancel-shipment link relation, it means that the item in the order is allowed to be cancelled at the present moment. But imagine what the resource might look like after it's shipped and the request is made several days later:

{
  "name": "Gadget 1",
  "price": "16.99",
  "status": "SHIPPED",
  "_links": {
    "details": { "href": "/item/a631723d69/details",
                 "method": "GET")
  }
}

The cancel-shipment link relation would no longer be returned from the server, because it's no longer a permissible operation (i.e., you can't cancel an order after it's been shipped).

More traditional access control can be managed in the same way (i.e., don't send the cancel-shipment link to a user who isn't authorized). Suppose the order hasn't shipped yet and your spouse can see what it is you've ordered but is not allowed to cancel it. They'd get this back:

{
  "name": "Gadget 1",
  "price": "16.99",
  "status": "ORDERED",
  "_links": {
    "details": { "href": "/item/a631723d69/details",
                 "method": "GET")
  }
}

So in summary, the links returned in each response encapsulate and represent what the requestor is authorized to do at any given moment in the system.

In any case, you must check for appropriate authorization on the server for the request being made, as you never know when someone may be hacking around with raw URLs.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top