WoW APIs - Android Authentication

API Discussion
Hey everyone! I recently started experimenting with the WoW community APIs, and I have a few questions for which I didn't find any answers in the forum, hope somebody might be able to shed some light on this! :)

So, I have some experience with Android development, and I wanted to use the Blizzard APIs to show some data on the app i'm playing with. Searching in these forums, and the web, I noticed that in the past, someone could register their application (as I understand it) and receive an API key that they would use in order to pull the data they required. However, looking at more recent posts, and experimenting with the API at the API reference page, I noticed that an authentication token is required to get the required information.

If i'm not missing anything, as I understand it, the way someone would go about it would be to have the user log in to battle.net with their account details, and that would generate a temporary 24-hour token which I can use to access data. However, seeing as I do not want to have access to any account specific data (I primarily want to access a guild roster, something openly available at the armory site), it seems that, having the user log in to a newly installed application, just for getting data that is accessible on the web without a login required, feels a bit off.

So the way I see it, the more reasonable way would be to use my client ID and client secret, to create a token without a scope (thus a token which can only access community APIs, not player account information) and use it to perform the request for the data.

Assuming all the previous is correct (which may not be, please correct me if I'm wrong), I would need to embed my client ID and client secret to my application, so that it can create tokens. However I find that to be unwise, since anyone who would decompile the app would have access to my client credentials (client ID and client secret) which would be a security risk. To counter that, the only way I had in mind, was for me to be creating a new scopeless token once every approximately 23 hours, and have it posted on a website where the app would look it up, and use it to request guild roster information. This, of course, requires me to have a server to post the new token to, every 23 hours. I read that a token refresh request is not currently available, therefore I couldn't think of anything else, like using a static token (kinda like the old API key), and refreshing it upon expiration.

Well, I'm terribly sorry for the length of this post, but it's my first time using the OAuth system, and I think there's really only 2 possibilities: either I'm right and I have to create a new token every 23 hours, or I could very well have it all wrong, and I'm missing something critical. Either way, any help would be greatly appreciated!! ^^
One option is to create your own web app that proxies battle.net API requests for your Android app. That way you don't expose your client id and secret to users of your android app. You can secure. encrypt, mangle or use whatever APIs you want between your Android app and your web app (to prevent other folks from "poaching" your backend services).

As a side note:

If you did want to use the profile APIs, you would have the user log into battle.net in their web browser, which after authorizing your app to access to their profile, would redirect them to your web site where you could capture the authorization_code. You can use the state parameter in the authorization request and redirect to tie the authorization code back to the Android app user. You would then exchange the authorization code for an access token, which you would store in the web app (and associate with the Android app user).
11/16/2018 04:31 AMPosted by Dawg6
One option is to create your own web app that proxies battle.net API requests for your Android app. That way you don't expose your client id and secret to users of your android app. You can secure. encrypt, mangle or use whatever APIs you want between your Android app and your web app (to prevent other folks from "poaching" your backend services).

As a side note:

If you did want to use the profile APIs, you would have the user log into battle.net in their web browser, which after authorizing your app to access to their profile, would redirect them to your web site where you could capture the authorization_code. You can use the state parameter in the authorization request and redirect to tie the authorization code back to the Android app user. You would then exchange the authorization code for an access token, which you would store in the web app (and associate with the Android app user).


This is very interesting information. I am still scouring the web to find a way to do this without creating a web site to use as a proxy, as I do not have any experience with web development, and was thinking about creating an Android-only app. It is good to know though, as a backup plan, thank you!!
I am kinda in the same boat as Arcael as I'm working on an iOS app for raid leaders to check participants' characters, so I only need simple "public" data access to characters, like the Armory.

This worked fine with the Mashery API where you only needed a key, however, now with the new Blizzard API and the 24h token it seriously hampers my app to do this seemingly simple function.

The solutions suggested are valid and interesting, but I think it feels it is overkill for something that should be relatively simple. And like Arcael, my web experience is too limited at the moment to set something like that up quickly, plus you'd need a web server at your disposal.

I am also very interested to see if someone knows of a different solution.

Come to think of it, Dawg6's site "https://apitest.dawg6.com/apitest/" is kind of the solution we would need to make our apps be able to run from now on unless Bliizard changes their API rules. Until then I feel I have to stick with the Mashery API which is a shame as the Blizzard API is much faster.
11/25/2018 02:19 AMPosted by Aecasorg
Until then I feel I have to stick with the Mashery API which is a shame as the Blizzard API is much faster.


Just be aware that the Mashery Gateway is going to be deprecated at the end of the year. So you'll be blocked at that point if you do not find a solution that works for you to move over the the new Gateway.
I created a simple URL proxy that you can use. You can even host it on a free site like heroku.

Here's a link to the Github site:

https://github.com/dawg6/bnetapiproxy

I also have a live demo available at:

https://bnetapiproxy.herokuapp.com/

just add the blizzard API url at the end, e.g.:

https://bnetapiproxy.herokuapp.com/https://us.api.blizzard.com/wow/realm/status?locale=en_US
11/25/2018 02:19 AMPosted by Aecasorg
I am kinda in the same boat as Arcael as I'm working on an iOS app for raid leaders to check participants' characters, so I only need simple "public" data access to characters, like the Armory.

This worked fine with the Mashery API where you only needed a key, however, now with the new Blizzard API and the 24h token it seriously hampers my app to do this seemingly simple function.

The solutions suggested are valid and interesting, but I think it feels it is overkill for something that should be relatively simple. And like Arcael, my web experience is too limited at the moment to set something like that up quickly, plus you'd need a web server at your disposal.

I am also very interested to see if someone knows of a different solution.


So, I just tonight finished testing various aspects of the things I tried, so 'll leave this here for future reference! :)

The way I went about it, I actually followed Dawg6's advice and created a web app. I used Google apps script, which uses javascript (or rather a stripped down version of it) to run scripts and return data (took less than 3 hours of searching and reading to learn the parts I needed, so it is relatively easy). The way I did it, was this: if the token in the app has expired, go to the web app, and fetch an updated version. Save the new token locally (in android that would be SharedPreferences with access mode set to private, so on unrooted devices only the app can access it), and keep using it until it expires.

Now obviously, this doesn't solve the token update problem, but it moves it from the app, to a file in your google drive (remote update possible! yay!).

So there is a step two, in which I created another script which only I can access (by being logged in to my google drive), and where I can submit a new token, which is then requested by the first script, and saved in its persistent storage. After that, I wrote another program (actually another app which runs on a spare android device), which gets the key from the first script, checks with blizz api to receive the expiry date (given in Unix time*) and waits until the expiry date has passed to go fetch a new key, notify script 2, which in turn has the data ready for when script 1 asks for it.
*Careful with Unix time, and Unix time milliseconds. If it is milliseconds divide by 1000 to get proper time in seconds, and vice versa.

If you go about it this way (not the most elegant way, I know), you will need to google how to call a URL from a script and get the result (to call 2nd script), how to use the script's PropertyService (to save the key to the script's persistent storage), and how to return the key in the URL reply stream (in Android, that would be the HttpUrlConnection getInputStream() method). Little hint: it is "ContextService.CreateTextOutput(<YourTokenHere>)".

Obviously this means storing data locally (like the token, so as not to risk exceeding google apps script quota, and recent character public information, to avoid exceeding blizz api quota), and also exposes your token to any third party who would want to put in the extra effort for getting it, but as long as the token has no scope, it would be the same as someone acquiring your APIKey (aka, no personal data at risk). Of course there is also the option to implement encryption between the script and your app, but since no personal data can be made available from the information someone could possibly "steal" from you, I believe it is kinda overkill.

Sorry for the long reply, but I just managed to bring my app to a "Release Candidate" status after a lot of debugging (as is natural :p ) and as I said I just finished solving (I hope) the token refresh problem tonight, so I wanted to leave this here for anyone who would wanna do it this way, to avoid having to set up a server at home (or buying a hosting service online), for future reference!
Also, re-reading my reply, I must note that the terms "key" and "token" mean the same thing, I use them interchangeably in my head. xD

Hope I helped without getting you bored from reading! ;)
Wow you guys! Great work! (I thought you'd get notified when ppl posted to threads you participated in...)

11/25/2018 09:26 AMPosted by Dawg6
I created a simple URL proxy that you can use.

Dawg6, thanks for the URL proxy! Really appreciated! I'll try it out.

11/25/2018 09:03 PMPosted by Arcael
So, I just tonight finished testing various aspects of the things I tried, so 'll leave this here for future reference! :)

Arcael, interesting solution. I'll have to re-read it a few more times to fully understand it. :D If you don't mind me asking, what is it you're working on? I'm a bit curious.
11/25/2018 06:53 AMPosted by spudnic072
11/25/2018 02:19 AMPosted by Aecasorg
Until then I feel I have to stick with the Mashery API which is a shame as the Blizzard API is much faster.


Just be aware that the Mashery Gateway is going to be deprecated at the end of the year. So you'll be blocked at that point if you do not find a solution that works for you to move over the the new Gateway.

Yeah, I'm aware, thanks. Thankfully the guys above have been really busy and provided solutions for the community. Love it!
11/28/2018 08:23 AMPosted by Aecasorg
Arcael, interesting solution. I'll have to re-read it a few more times to fully understand it. :D If you don't mind me asking, what is it you're working on? I'm a bit curious.


It would indeed be useful if we could get notified about replies to a forum post xD

So, in short, it is an app for getting information about the members of a guild, and some more detailed info about their progress (so far in PvE, specifically raids).

By the way, I realize that the way I implemented the token refreshing, can be done without the extra device, by just having the second script refreshing it directly when the old one expires. I just posted the way I did it, because I want to have direct control of the token refresh process, without having to alter the script and push a script update, and also I prefer not having the scripts perform any long operations, I know Google allows them to run for a couple of minutes (I think) and that would be good enough, but I wanted to minimize that, that's why I used a spare device as I said in my previous post. Just mentioning in case anyone wanders why one would go the "use 1 extra device" way.

Cheers :)
11/30/2018 07:01 PMPosted by Arcael
So, in short, it is an app for getting information about the members of a guild, and some more detailed info about their progress (so far in PvE, specifically raids).

Thanks for that. Sounds very interesting and it is a somewhat similar to what I've been working on on iOS. I would be happy to assist you (for free) if you wanted to do an iOS version (I need another project in my portfolio). My project is here: https://github.com/Aecasorg/WoWilvlChecker. Please feel to contact me.
I have written my OAuth in react native with a webview, if the users logs in and will be redirected I catch the redirect_url, parse the access_token and save it for the requests. I guess this could be done also with the native webview.
12/02/2018 12:27 AMPosted by Aecasorg
Thanks for that. Sounds very interesting and it is a somewhat similar to what I've been working on on iOS. I would be happy to assist you (for free) if you wanted to do an iOS version


Thank you very much, that is very kind of you! However I do not own an iOS device, therefore it has never crossed my mind to go into iOS development, I know literally nothing, and even if I did develop something, there would be now way for me to maintain it (I do not see myself moving away from Google's ecosystem, too much of a hassle). ^^

12/02/2018 12:53 AMPosted by ZeroCool
I have written my OAuth in react native with a webview, if the users logs in and will be redirected I catch the redirect_url, parse the access_token and save it for the requests. I guess this could be done also with the native webview.


Yes, that is the way you are supposed to do it in order to access user's information (list of characters on a bnet account, etc). However, the thing is that, the info I am asking for, for my application, is not user data, rather than public data, so the idea is to access it without having to log in at all.

Join the Conversation

Return to Forum