ArenaNet Staff Daniel Snider.6241 Posted May 21, 2019 ArenaNet Staff Share Posted May 21, 2019 Hello all,I put together a quick change to the API to allow some more fine-tuned control over sharing API keys a few weeks ago, and I had a chance to deploy it today. I have added an endpoint for creating what I'm calling "subtokens". Recent API UpdatesFirst, here is the change in list format:Added the /v2/createsubtoken endpointSubtokensAs a warning: this change's uses are niche.A subtoken is a special API key that can be used anywhere a normal API key can be used. It is simply a wrapper around a regular API key with reduced permissions. It can be created by accessing /v2/createsubtoken with several options:Subset of permissions (e.g. account, inventories)Expire timeList of urls that can be accessed (optional: if no urls are provided, then all urls are allowed)Here is an example that shows the full functionality:GET https://api.guildwars2.com/v2/createsubtoken?permissions=account&expire=2019-12-25%2012:34:56&urls=/v2/characters/My%20Cool%20Character,/v2/account/home/catsAuthorization: Bearer MY_API_KEYThe API will respond with:{ "subtoken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ3YlRodVdNNGExMUduZlpYSTdaa0pHck52 SVVPUWhMejZHTXpOeE9TUC1rIiwiaWF0IjoxNTU4Mzk3OTUwLCJleHAiOjE1NzczMDYwOTYsInBlcm1pc3Npb25zIjpbIn Byb2dyZXNzaW9uIiwiYWNjb3VudCIsInVubG9ja3MiXSwidXJscyI6WyIvdjIvY2hhcmFjdGVycy9NeSUyMENvb2wlMjBD aGFyYWN0ZXIiLCIvdjIvYWNjb3VudC9ob21lL2NhdHMiXX0.UdLlafgo8lxkb1Hn88paZT83aw_9mHEYVZJLDgObNSc"}I can then see what cats I have unlocked with this large subtokenGET https://api.guildwars2.com/v2/account/home/catsAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ3YlRodVdNNGExMUduZlpYSTdaa0pHck52SVVPUWhMejZHTXpOeE9TUC1rIiwiaWF0IjoxNTU4Mzk3OTUwLCJleHAiOjE1NzczMDYwOTYsInBlcm1pc3Npb25zIjpbInByb2dyZXNzaW9uIiwiYWNjb3VudCIsInVubG9ja3MiXSwidXJscyI6WyIvdjIvY2hhcmFjdGVycy9NeSUyMENvb2wlMjBDaGFyYWN0ZXIiLCIvdjIvYWNjb3VudC9ob21lL2NhdHMiXX0.UdLlafgo8lxkb1Hn88paZT83aw_9mHEYVZJLDgObNScand get normal results.The request will be rejected if:The reduced permissions do not meet the permission requirements of the endpointThe subtoken time is expiredThe request url does not match the restricted url set (unless there are no url restrictions)The original API key which was used to create the subtoken is deletedSubtoken usesAs I admitted earlier, there aren't a huge amount of uses for a subtoken. Here are the two use-cases I considered while making this change:First and foremost, subtokens lets an app (App 1) accept & store an API key from a player and then pass that API key on to another app (App 2) with more control over what App 2 can do with the player's key.The other case is for savvy users who want more control over what they share with their API key. They can use the endpoint to generate subtokens to hand over to apps with, e.g. expire times or restrictions to certain character endpoints.I'd love to hear thoughts and feedback for this change, as well as any bug reports.Thanks!SniderEDIT: Added a bit about deleting the original API Key Link to comment Share on other sites More sharing options...
Illconceived Was Na.9781 Posted May 21, 2019 Share Posted May 21, 2019 Thanks for the post, @Daniel Snider.6241I love the regular communication about plans and changes.I'm looking forward to seeing how the fan-devs use the subtoken. Sounds very promising. Link to comment Share on other sites More sharing options...
DragonFury.6243 Posted May 21, 2019 Share Posted May 21, 2019 I am loving these changesLove the communications Link to comment Share on other sites More sharing options...
Karasu.9483 Posted May 21, 2019 Share Posted May 21, 2019 This is a ridiculously awesome and underrated update. Thank you so much for your work in continuing to expand and your support of the API. Link to comment Share on other sites More sharing options...
ArenaNet Staff Daniel Snider.6241 Posted May 21, 2019 Author ArenaNet Staff Share Posted May 21, 2019 A quick update:Some users have already pointed out some bugs with the new /v2/createsubtoken endpoint. Those have been fixed.I have also changed /v2/tokeninfo to understand subtokens, given a recent schema version parameter (e.g. ?v=latest).If you see any more issues, let me know. Thanks! Link to comment Share on other sites More sharing options...
Aens.2713 Posted May 22, 2019 Share Posted May 22, 2019 Can we create endless subtokens? Link to comment Share on other sites More sharing options...
Steven.6309 Posted May 22, 2019 Share Posted May 22, 2019 Hey I'd be careful with allowing GET with createsubtoken because it has different semantics that (maybe some) clients use to decide whether to cache the response.In general a GET should be idempotent (asking a question should not change the answer). Link to comment Share on other sites More sharing options...
ArenaNet Staff Daniel Snider.6241 Posted May 22, 2019 Author ArenaNet Staff Share Posted May 22, 2019 @Elrey.5472 said:Can we create endless subtokens?No. I decided to start with a required expire time and a maximum. I figured the endpoint should start more restrictive, then wait to see if we need to loosen the restrictions depending on app developers' needs. Link to comment Share on other sites More sharing options...
ArenaNet Staff Daniel Snider.6241 Posted May 22, 2019 Author ArenaNet Staff Share Posted May 22, 2019 @StevenL.3761 said:Hey I'd be careful with allowing GET with createsubtoken because it has different semantics that (maybe some) clients use to decide whether to cache the response.In general a GET should be idempotent (asking a question should not change the answer).You're right, it really should be POST. I chose GET because for API internal reasons POST is much harder and I wanted to get a fast turnaround on this feature.That said, I think GET is OK here because it's still a stateless call: the subtoken parameters are just stored in the subtoken itself. Nothing is written and no state is modified on the API server-side when /v2/createsubtoken is accessed. Link to comment Share on other sites More sharing options...
Steven.6309 Posted May 30, 2019 Share Posted May 30, 2019 Yep that sounds totally fine then.I'm implementing access to this endpoint now and I noticed that it's possible to create a token that has no permissions. It's also possible to create a token with an "exp" that is before its "iat". Example: GET /v2/createsubtoken?expire=2018-05-30T13:08:13eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJZZEVvTnRjQkJ1YnF5UmxoZWdPZC1iWGktMUxfd3NxQm1aV0x5YTlXd09ZIiwiaWF0IjoxNTU5MjIxNjkzLCJleHAiOjE1Mjc2ODU2OTMsInBlcm1pc3Npb25zIjpbXX0._Jsmtm8bUkqIWthjcIEG8eNAfM4Npp8x5Br5rsglMvINot even /v2/tokeninfo accepts this token. I'm not sure if the service should be handing out tokens that are practically useless? Link to comment Share on other sites More sharing options...
ArenaNet Staff Daniel Snider.6241 Posted May 31, 2019 Author ArenaNet Staff Share Posted May 31, 2019 Hmm. Some non-static endpoints require an access key but do not require any permissions. Off the top of my head, I believe /v2/tokeninfo doesn't require any permissions. Maybe that endpoint was built that way because it assumes account is always set.I'm not sure why you'd want to generate a token that expires in the past. I could have it error when exp < iat, but there's not a whole lot of benefit other than helpful sanity checking for the user of the endpoint.Also, if I have time at some point (and I remember), I'll put some cache-control properties in the response headers to tell the client not to cache the endpoint since it does change on every refresh due to iat being encoded in the response. Link to comment Share on other sites More sharing options...
Steven.6309 Posted June 1, 2019 Share Posted June 1, 2019 Thanks for the detailed response.Off the top of my head, I believe /v2/tokeninfo doesn't require any permissions.I've been trying some things and I've seen tokeninfo return 403 Forbidden under a few circumstances:Token is expired (exp < now())"urls" is used but does not include "/v2/tokeninfo"Race condition?I'm not sure about the last one but if you do:let subtoken = GET /v2/createsubtokenlet tokeninfo = GET /v2/tokeninfo?access_token={subtoken}The second call sometimes fails. Adding a delay between the first and second call seems to help. I don't know how that's possible if the first call does not write state? Link to comment Share on other sites More sharing options...
Steven.6309 Posted June 4, 2019 Share Posted June 4, 2019 @"Daniel Snider.6241" is it possible that /v2/createsubtoken and /v2/tokeninfo run on different machines with different system clocks? Is it possible that those clocks are not synchronized? I often get "Invalid access token" from tokeninfo immediately after the subtoken is created. If there's no state then I'm guessing you use the "iat" claim to check if the token is valid... or some weird signing algorithm that's also time-sensitive. Link to comment Share on other sites More sharing options...
Steven.6309 Posted June 28, 2020 Share Posted June 28, 2020 Is it possible to make URL restrictions less strict?If I create a token with urls=/v2/characters then I can get /v2/characters?ids=all but not a subset like /v2/character/My Awesome Character. Link to comment Share on other sites More sharing options...
Chromazene.4807 Posted June 29, 2020 Share Posted June 29, 2020 Why are all the third party websites still having outdated utility/spec descriptions? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now