I'm working on a service that forwards/unifies our API calls to external platforms/services. For
For example, let's say that I don't want to handle posting toall possible actions (create post, retrieve post, edit post, list posts) for Facebook, Twitter, LinkedIn and, Google+ at each user-facing service. So the user-facing services calls this API forwarder with a message, somehow specify the service to post to and on behalf of which user is the request coming from.
To forward the call successfully, I need to identify:
- the calling service, for which I use the Authorization header.
the calling service, for which I use the Authorization header.
- the service to which to forward.
the service to which to forward.
- the user who initiated the request. I shouldn't store end user external service credentials (e.g. facebook tokens) in the calling service but in the forwarding service.
the user who initiated the request. I shouldn't store end user external service credentials (e.g. facebook tokens) in the calling service but in the forwarding service.
I have a few options on how to pass this data, and any input would be appreciated:
- Specifiy service and user as sub-resouces in URL
/service/{externalServiceName}/user/{userReference}/Object/{objectId}
E.g. GET /service/facebook/user/uid123/posts/post345
This feels quite verbose to me.
- Use query parameters.
/Object/{objectId}?service={externalServiceName}&user={userReference}
E.g. POST /posts?service=facebook&user=uid123
- Overload the Authorization header with:
Bearer: <OAuth token>, Service: <serviceName>, User: <userReference>
Resulting in nice URLs (GET /posts/).
This seems totallyThis seems totally out of spec though. Turns out ofspecifying multiple values for a header separated by comma is in the spec though.
- Use custom headers:
X-APIUnify-Service: <serviceName>
X-APIUnify-User: <userReference>```
<userReference>
Again,
Again, with nice, short URLs (POST /posts/post345).
- Use a mix of custom headers and resources in URL:
GET with
Authorization: nice,Bearer: short<OAuth URLstoken>, (`POSTUser: <userReference>
/posts{externalServiceName}/post345`)Object/{objectId}
This makes sense to me because: 1. the userReference is actually a second layer of authorization anyway. 2. The service is the resource that owns the Object. I.e. the same objectId can point to different resources in different services.
- Use JWT to pass the service and user, signed with the calling service secret.
JWT.payload = {
"callingServiceId": "5aafcd909c9a25054c3019e3",
What do you"externalServiceName: think?"facebook",
Thank you! "userReference": "uid123",
"iat": 1521638763
}
Authorization: Bearer: <JWT>
Thank you!