tobyzerner / json-api-server

A JSON:API server implementation in PHP.
https://tobyzerner.github.io/json-api-server/
MIT License
63 stars 21 forks source link

Authentication-specific endpoints #83

Closed bertramakers closed 9 months ago

bertramakers commented 9 months ago

Hi!

Maybe my question is more about JSON:API in general, but I'm wondering how to implement endpoints related to authentication in this library. To actually authenticate I guess an OAuth2 flow would be the most straightforward and wouldn't require any support from this library or JSON:API in general.

However once the client has received a token, they will probably want to fetch some info about the current user that has authenticated.

In the past I would implement that with an endpoint like this:

GET /api/user
Authorization: Bearer <OAuth2 token>
Accept: application/json

And the response could look something like this:

200 OK
Content-type: application/json

{
  "username": "foobar",
  "name": "John Doe",
  "picture": "https://...",
}

In some cases this info could also be embedded in the OAuth2 token if it's a JWT without encryption, but that is not always the case so the need for an endpoint like this is still valid I think.

Now that we're using JSON:API in our application, I would also like to provide an endpoint like this in a way that support JSON:API features like including related resources, sparse fieldsets, etc.

A possible solution I had thought of so far is that I'd implement an endpoint like GET /api/users/:id. This could be done like any other resource. However since an API client would (probably) not know the id of the user that they got a token for, I'd also need to provide a way to get the user related to the token. To do that I thought of two potential solutions:

However before implementing this, I was wondering if you had any feedback on how you would handle this instead?

One downside I can think of is that I need to make sure I don't leak any sensitive information in the /api/users/:id endpoint, or restrict access to only the id of the currently authenticated user. But that is manageable I think.

tobyzerner commented 9 months ago

Hi @bertramakers! I think both of your proposed solutions sound good and don't have preferred one. The JSON:API spec is pretty agnostic on what URL structure you choose to use, only making some recommendations.

In my own app I've just gone for the GET /api/user endpoint. I implemented it with a controller which simply passes a request to my API controller and returns the response:

abort_unless($id = Auth::id(), 401);

$apiRequest = (new ServerRequest('GET', "users/$id"))->withQueryParams($laravelRequest->query());

return (new ApiController())($apiRequest);

Closing as I think this is not something that this library needs to have a position on, but happy to keep discussing!

bertramakers commented 9 months ago

I hadn't thought of forwarding the request internally. Thanks for the help!