-
-
Notifications
You must be signed in to change notification settings - Fork 923
Closed
Description
I am trying to figure out something that unfortunately I haven't been able to find an example for.
I have a very simple API that currently only exposes one route
/api/users/{id}
If I pass an ID to the route.. I get back a User object.. Great!
Now I have an app that is using oauth to authenticate.. get access_token, refresh_token, etc.
I now have an access token I can use to access the API. Except.. I don't know my own ID. The authentication call doesnt return it.. it only returns an access_token.
I want to create a route
/api/users/me
is this the correct way to do this ? Would I only need a custom data provider? do I need to implement a full custom controller ?
trying to understand the best approach, best practice for this scenario.
Activity
yecraftsman commentedon Mar 19, 2016
I solved this question by adding a simple
MeController
eg. if you use a Bearer token to authenticate the user :
if the user ID is stored in the token information, you don't need to use EntityManager.
jayesbe commentedon Mar 19, 2016
@yelmontaser Ah.. so you basically side-stepped the api-platform ? Did you try implementing a solution within the platform and gave up ?
dunglas commentedon Mar 19, 2016
You should provide an ID as it's not optional. A solution is to provide a fake id (
me
for instance).But be careful, creating endpoint like
/api/users/me
isn't stateless, can create cache problem if you rely on some reverse proxies and break the REST pattern. It's better from a design POV to keep with/api/users/{id}
and for instance use the Symfony Security Component to ensure that only the current user can access the endpoint corresponding to its id.jayesbe commentedon Mar 19, 2016
@dunglas That makes sense to me. However im not looking to override the /api/users/{id} endpoint..
at the moment I have been able to create a custom controller and service.. the documentation appears as such
I havent implemented the controller just yet.. however because I am authenticated im sure I can fetch the id out of the token and forward to the /api/users/{id} endpoint.
is that a secure enough solution ?
I guess another option is to expose the oauth entities. I could expose the AccessToken entity since I have an access token.. to return the user via AccessToken. Would this be a better alternative ?
jayesbe commentedon Mar 19, 2016
Is there an example of this ?
jayesbe commentedon Mar 19, 2016
I added both an AccessToken resource as well as a custom get service.
http://i.imgur.com/nnpaTAC.png
Interestingly.. I added the @Security annotation to the custom service controller..and it added the little 'keys' icon denoting that the method requires authentication. The other methods don't have that though a valid oauth token is required to access any of the service endpoints.
Currently the AccessToken resource requires a numeric id.. this needs to be converted to a string identifier. It doesn't really make sense that since you need an access_token to access any of the services.. that you should need an AccessToken resource. Since in order to access /api/me requires a valid access_token.. and the token only lasts an hour.. the /api/me custom service seems like the best approach for this scenario.
Thus.. here is my controller for the /api/me endpoint
thanks @yelmontaser for that bit at the end.
@dunglas Your thoughts ?
jayesbe commentedon Mar 19, 2016
Im also wondering.. if its possible to have that little 'keys' icon.. appear next to all the methods ?
yecraftsman commentedon Mar 19, 2016
@jayesbe already implemented but not on the path of the resource as
/api/users/me
rather/me
like Facebookhttps://graph.facebook.com/me
it's 100% stateless.The use the annotation
@Security
is a good idea and a best practices.yecraftsman commentedon Mar 19, 2016
@jayesbe if you extend
ResourceController
you don't needforward
.jayesbe commentedon Mar 19, 2016
@yelmontaser thanks for the tip.
robertfausk commentedon Apr 3, 2016
@yelmontaser @jayesbe What about writing a bit of documentation for this and afterwards close this issue?
jayesbe commentedon Apr 3, 2016
I don't mind adding some doc, where is the best place to add it ?
soyuka commentedon Apr 4, 2016
http://github.com/api-platform/doc
2 remaining items
remoteclient commentedon Mar 19, 2018
I also looked for a way to get the id so that a logged in user can access its profile. As a /me route seems to be not cachable and I use LexikJWTAuthenticationBundle there is no need for a route like this. The bundle can send additional data beside the token. (https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Resources/doc/2-data-customization.md#eventsjwt_authenticated---customizing-your-security-token)
Like described there, I set up a listener which includes the users id in the response:
or put it directly in the token:
Retunsky commentedon Feb 20, 2020
Solution posted by @lyrixx didn't fit me because it doesn't allow you to set different serialization groups on "get" and "get_me" operations. So my solution based on custom actions:
It allows you to set different serialization groups or even disable "get" operation. The only one restriction is that users must have integer ids. Hope it helps someone.
waspinator commentedon Apr 27, 2020
@Retunsky this seems to change the hydra member @id parameter to match the path. Do you know how to keep the
/users/1
IRI path instead of changing to/users/me?id=1
I see my problem now. The order of the
"get"
annotations is important. works now as expected.soyuka commentedon Jun 10, 2020
Another solution for this is to catch
me
and transform it to an identifier via the identifier denormalizer: https://gist.github.com/soyuka/c25aa66728439eec56419a5a2029559218 remaining items