MinecraftAdministrationCenter / mac-docs

Public documentation for the administration panel(both API and UI).
MIT License
0 stars 0 forks source link

RESTful API - Request & Response Structures #2

Open FastFelix771 opened 7 years ago

FastFelix771 commented 7 years ago

I want to set some standards for the HTTP Requests and Responses when communicating with the backend.

First, the unencrypted request body itself:

{ token: "auth token", content: { /* this contains the individual content of the request */ } }

The token field has to be present in all requests to the backend. It may contain a slave token of some client, or the master token.

The content has to be a JSON object that acts as root object and may contain any child values / objects, depending on the request.

Both token and content are also encapsulated in an anonymous json object.

According to this, the request body has to be encrypted. So, the encrypted request will look like this:

{ content: "BASE-64 encoded body" }

To prevent encoding issues, the content will be encoded with base64 before being sent to the backend.


Now, the 2 possible responses from the backend, either a success or a failure:

Response in case of success: { success: true, content: "BASE-64 encoded body" }

success set to true indicates that the request was authorized and overall successful. content is the the "true" response body, containing the returned data.

According to this, the content field has to be encrypted. To prevent encoding issues, it will be encoded with base64 before being sent to the client. After decoding and decrypting it, the content field may be a JSON object, or a JSON array, instead of a plain value. This keeps a consistent format accross different responses.

Response in case of failure: { success: false, content: "SIMPLE_ERROR_MESSAGE" }

success set to false indicates that the request was not authorized or otherwise unsucessful. content is a static error message, explaining the type of exception that occurred, something like "INVALID_TOKEN" or "INSUFFICIENT_PERMISSIONS" for example.

Unsuccesful responses won't contain any sensitive data, so there is no need to encrypt it.


Like with the request bodies, success and content are always encapsulated in an anonymous json object.

For some requests and responses, there is no need or possibility to be sent encrypted. For example public endpoints providing the encryption key of the backend, or similiar public accessible informations.

FastFelix771 commented 6 years ago

{ token: "auth token"...

A minor correction here: Since GET Requests should not contain bodies, we would have no way to authorize private GET Endpoints. And beside that, its usual to send the authorization token with the HTTP HEADER.

So, we should, instead of attaching the token to each request body, add an Authorization Header, like this:

"Authorization: Basic BASE-64 encoded token here"

The token will be encrypted via RSA using the backends public-key, before it gets BASE-64 encoded. I'm not sure how well this works with firewalls and reverse-proxies, though.

@jens1o Do you know a better way to achieve this, or do you think that will work well enough?

jens1o commented 6 years ago

We could also use OAuth for this.

FastFelix771 commented 6 years ago

I've read about oAuth(2) - I'm not sure if it fits in this case. But on the other hand, im generally thinking about how to integrate that token mechanism without locking out other authentication providers like LDAP / ActiveDirectory.

Perhaps we could generate the master token on first start - and make it configurable instead of static. We could even accept a token as start parameter on the backend agent, which will be used master token. With the master token then, other tokens (slave tokens) can be generated via the Web API by using a client.