Working on a REST framework that will support multiple hypermedia types and authentication. One thing I'm not really sure how to handle are sensitive values in the resources. For instance, if I were to include user management in the API, I would need a way to expose to the client that there was a field for the password, but not show the actual password hash. Same thing with a credit card. If I don't, it would violate the hypermedia constraint as knowledge of the fields would become out of band, and make my HATEOAS broken.
Here's an actual use case that I've encountered:
The project is a directory of people that showcases them so others can hire them. There are two types of users: those with profiles, and those without. The design around the resources would be /users/{userid}
for a user and /users/{userid}/profile
or /profile/{profileid}
which would include a link back to the user so the client could get things like the user's name, etc. Also, the user would be able to store a credit card at /users/{userid}/creditcards/{creditcardid}
.
To display a user's profile, you would also need the user resource to have access to the names and whatnot. What we don't want is to expose the user's password on the user resource, or the credit card links. I think I can just hide the credit card links without any issues, but I'm not sure about the password field. Should I just expose it for the authorized user, but not on the other user models? I should mention that only GET
is allowed on users unless authenticated and authorized.
One weird edge-case that would emphasize this would be an object you have partial access to change. Say you were a low level admin who had access to change the user's name and address, but not password. Since you don't have access, you can't expose the password field. How can I do a PUT
to a resource that I don't have all the fields to? Should I just use PATCH
in those cases?
TL;DR: How do I properly hide/expose fields in a REST API and also follow the hypermedia constraints?
First, always use SSL when there is sensitive information. If you use SSL, your request will be encrypted. Even the URLs are encrypted over the network. However, there are lots of other places where those same URLs may be logged in clear text (e.g. proxy servers, load balancers, dns servers), so it's important not to put any sensitive information in the URL.
So what does that mean for your REST API? Well, first of all, don't use sensitive information in IDs. Your credit card number may be unique, but don't use that as the identifier of the card.
Also, never return a password when getting a resource. You should be filtering this type of information out at the server. You can accept it in a request body but it should never be sent back in a response body.
To your other weird edge case, PATCH is not yet a standard. Until it becomes one, I've seen a lot of people using POST to do partial resource updates. POST does not have to be idempotent, so it actually makes a lot of sense. So, POST is partial update and PUT is create or replace at a given ID. Sound good?
If you haven't watched Les Hazlewood's talk on HATEOAS yet, I would suggest you do so. It gives a pretty good overview of the best practices.
来源:https://stackoverflow.com/questions/19072759/how-to-handle-sensitive-properties-in-a-restful-api-such-as-passwords-credit-c