Comments (28)
Alright figured it out, this is what you have to do:
- Get some sort of web-client (HTTPClient can do this) to get the token from https://accounts.google.com/o/oauth2/auth?client_id=848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=openid%20email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email
- Post to https://accounts.google.com/o/oauth2/token as x-www-form-urlencoded with the following key-value parameters:
grant_type :authorization_code
redirect_uri: urn:ietf:wg:oauth:2.0:oob
scope: openid email https://www.googleapis.com/auth/userinfo.email
client_secret: NCjF1TLi2CcY6t5mt0ZveuL7
client_id: 848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com
code: __YOUR-CODE-HERE__
- You now get a response such as this
{
"access_token": "ya29......",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "eyJhbG.......",
"refresh_token": "1/_2_U6VFBCyk......"
}
- Use the id_token to authenticate successfully (untested but should work).
A bit of information, the client_id and client_secret are available on any Pokemon GO installation to be retrieved so that's where they come from (I just googled them up)
As for urn:ietf:wg:oauth:2.0:oob (copy paste from Google)
This value signals to the Google Authorization Server that the authorization code should be returned in the title bar of the browser, with the page text prompting the user to copy the code and paste it in the application. This is useful when the client (such as a Windows application) cannot listen on an HTTP port without significant client configuration.
When you use this value, your application can then detect that the page has loaded, and can read the title of the HTML page to obtain the authorization code. It is then up to your application to close the browser window if you want to ensure that the user never sees the page that contains the authorization code. The mechanism for doing this varies from platform to platform.
If your platform doesn't allow you to detect that the page has loaded or read the title of the page, you can have the user paste the code back to your application, as prompted by the text in the confirmation page that the OAuth 2.0 server generates.
from poke-api.
Yes. Please read the README before posting an issue
from poke-api.
Sorry, I was unclear with what I meant. I meant is it possible to do authentication with Google rather than the API.
For example:
- Redirect a user to the google sign in page and retrieve an access token there
- Using that access token retrieve the endpoint for the API
- Continue to make requests as needed from there.
The purpose of this is to allow for a more secure login rather than inputting your username and password into the API.
from poke-api.
Yes, this should be possible to do as long as the token returned by Google works for Niantec (I have no idea about which scope it needs, but I assume it'll just be viewing their e-mail address). Here's some reference documentation: https://developers.google.com/api-client-library/ruby/auth/installed-app
I won't really get time before weekend to get this done, however, the only caveat is that machines that do not have a browser may not be able to authorize (in which case perhaps a URl can be given to visit and token can be be entered/set). We can also save the refresh token somewhere local (a file for example, Google's API client gem handles this) and keep using the refresh token to generate a new access token upon expiry.
from poke-api.
I'd say since this is just an API wrapper (with some extras), you can leave that implementation to the client that's integrating this gem.
That should be a basic oauth flow and you can even use omniauth-google-oauth2 (i.e).
I wouldn't consider that as a basic necessity for this gem and even more, I would consider it an overhead.
from poke-api.
I did try to implement it within my application with omniauth-google-oauth2 and ran into some problems. The steps I took were:
- Create a new Poke::API::Client
client = Poke::API::Client.new
- Successfully retrieve the access token
- Make a Poke::API::Auth::GOOGLE object instance (username and password as just fillers)
google = Poke::API::Auth::GOOGLE.new(@user.name, "password")
- Set the GOOGLE Object's @access_token instance variable to the access token received from google
google.instance_variable_set(:@access_token, @user.access_token)
- Set the client's @auth instance variable to google
client.instance_variable_set(:@auth, google)
- Fetch client endpoint
client.instance_eval{ fetch_endpoint }
The error comes when I try to fetch_endpoint:
Poke::API::Errors::UnknownProtoFault (An unknown proto fault has occured => [Unable to fetch endpoint, please try to login again. @ /Users/xxx/.rvm/gems/ruby-2.3.1/bundler/gems/poke-api-46e0d6d5761c/lib/poke-api/response.rb:41:in
store_endpoint']):`
Let me know if I missed anything. @elfenars
from poke-api.
@dphuang2 I read something about Niantic implementing cert-pinning on the endpoints now, I don't know if this applies to all the endpoints, but this sounds like either the endpoint changed or you're getting rejected.
Have you tried the vanilla solution for this API and see if it works anyway?
(Sorry I can't really try myself, the last time I used this was last Friday and the cert-pinning came out on Monday I think)
from poke-api.
Or maybe everything was good and the endpoint just failed... try again :(
Try debugging all the vars you set, including the @endpoint
in response.rb:41
... even better, post the full log of the client when you run it.
from poke-api.
Cert pinning its only enabled client side currently. Should not be an issue.
from poke-api.
Isn't omniauth
gem only for OAuth flow involving a web app (not a local program)? I have used it before but I remember needing a callback URL that will present a token to retrieve the access token.
from poke-api.
Yeah it is, I am working on a web app.
from poke-api.
Ah I see, should the api client only expose a way to store the access token by Google then to use? As you said it doesn't feel right to implement the entire OAuth flow. Provided the access token works (unsure at the moment).
from poke-api.
I ran some tests and comparisons.
I found that the @access_token of the GOOGLE Object from the client (from client.login) differs from the token I get from omniauth-google-oauth2. I assume that this is because omniauth uses Web login and poke-api implements the use of gpsoauth which is an Android login.
The two tokens I get back from omniauth look like this (I tried using both and both gave: "Unable to fetch endpoint, please try to login again."):
token="ya29.Rejijrq01231RJIAFJdaifijYjwiadhiR3921231jfdbajfkbaCfajkMWLrgZZHiLA"
id_token="eyJhbGciOiJSUzI1NiIsImtpZCI6ImQwZWM1MTRhMzJiNmY4OGMwYWJkgndjanfadkfenajkfndajkbfeaukaa.aREQRqu3dibqyibwfeakjdsbfakfeakhjfbadsjfeajkfnaksdljbcknasdfhrq8uw3hrufeJAJAINAW$FIJA$WFJAJIDSAFNA3nfaFNA#I#FNAfjA#FIANFaFIANDSKFNAFNADNSKFANCSKVAFNADSFNKXZMVKAFNSEKDFNAEISNFKASNFAEIWNFASNKFANSFDSAFJASDNFAESNFAJSNFADSNFajsfkansmfbadskfbaskdfbak2ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiMTcxMzk1MTQyMDk4LW92Z2piY2kzMXMxam5nOTB0dGMwOWtuYmZmOWM1NWZrLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiZW1haWwiOiJkeWxhbi5wLmh1YW5nQGdtYWlsLmNvbSIsImlhdCI6MTQ3MDI0NjgzOCwiZXhwIjoxNDcwMjUwNDM4fQ.vGQ364s5COriBeyhbsE7GUNrX9LyRbtlMyqqw_Bcf-W5zYJMw5Yfdiz1_QzFxfGAv-MP2-9h4I-6zKbL_QZwUNeVuYeHRGaoic16UGiZfSo3WF4zr-EZcdSnv7syCMx6gQsBIbCFIQLfpLy0JcaHlYFtt91hCoJJauO2cCq366E8qEuUE4zm5M7QhlyLnXWVt79of9nYWkzQBnZ6QuR9XXnEoFnCFxu-makaNdHKokm776WKgNMZtokrL4LeDp5rWwX7YBX2n79vCuJ-Q5dVviSQopFTJm5AQAcmHA_2YpAUaNojqwKVGz9REpYhqscCG0hbClIP8Paj0DqwT6nNZQ"
The access_token from GOOGLE Object looks like this (looks similar to the id_token from omniauth):
@access_token="eyJhbGciOiJSUzI1NiIsImtpZCI6IjM2ZTJlNDE5MzQxYjY5M2VjNDgyZDY2NzZiYWZjMzEzMzA2MWNhYWYifQ.fndjanfjkaenbfiabjkabfkasdjbfkabefkjaebfkbadjbfkjbadskjbvakjsbfnjkfaksfbeabfubjkeadbsfkabkebakjdbfjkasbjkfbaeklbnlabnfuaebfadsbfnmabskvmnb8ajksnefmaehjoiqhfoihqwiofhqwoifhqiwohfoqwenjfakbsdkjfbakfasfhafjheabkjfajkdshbfahjfdasjbnfukfgbhjeakjwhfiahlhjqraejkhruw4k5hw34789htugi3b3w98ufnb9i4f89iuw3dvb2dsZXVzZXJjb250ZW50LmNvbSIsImVtYWlsIjoiZHlsYW4ucC5odWFuZ0BnbWFpbC5jb20iLCJpYXQiOjE0NzAyNTA0MDEsImV4cCI6MTQ3MDI1NDAwMSwibmFtZSI6IkR5bGFuIEh1YW5nIiwicGljdHVyZSI6Imh0dHBzOi8vbGg0Lmdvb2dsZXVzZXJjb250ZW50LmNvbS8tVXgxTElzNmVlbDQvQUFBQUFBQUFBQUkvQUFBfQUFBQUFBTEEvWjVzd1NGR2MtYjQvczk2LWMvcGhvdG8uanBnIiwiZ2l2ZW5fbmFtZSI6IkR5bGFuIiwiZmFtaWx5X25hbWUiOiJIdWFuZyJ9.Er6weJIM-LMizaAPFUUJyjNE4oLWpjBWcDG50ogS6prjj1kZ57X9LIrZ_YZt8RgYcs4bCh-VZhX-bWNV3aXkMgoLX2YXtrHHmydlZ1wGiRq0qkpKyyv2Pj7nPaLmpxLCW9s7AflqNGdina26QUJEuApUy7CX3R-skHFcWMT-n76CzidIhGjOkWTRLv_AdhcpTtivd0tQ5coEqee_VGwUR8eQ_KfyxK4bZRZaXX6HNQFXSu3XdIUl6AXAUvYYfvT70MQWJ79XlTPQEyhOzCXsXChyotH_G5GgmQl2k1Wvc5txoQyYRHmHNDcKYLRmvtA3dV78aPnwuO9OBJFrfyDUkQ"
The point of comparing the two were to see if similar token lengths meant they were both compatible (that is why I tried using the id_token).
This is the line error is raised on:
def store_endpoint(client)
logger.debug "[+] Current Endpoint #{client.endpoint}"
if client.endpoint == 'https://pgorelease.nianticlabs.com/plfe/rpc'
--> raise Errors::InvalidEndpoint if @response.api_url.empty?
end
return if @response.api_url.empty?
logger.debug "[+] Setting Endpoint to #{@response.api_url}"
client.endpoint = "https://#{@response.api_url}/rpc"
end
It looks like using omniauth yields nothing when fetching an endpoint. Do any of you have an idea why the omniauth tokens do not work?
from poke-api.
Tokens that start with eY are JSON Web tokens, you should try and not share them (or garble them slightly) as they can share personal information (and are valid as well until expiry). I've edited your post so it's not valid a token anymore.
I believe the first token you get back is an authorization code
as described by RFC 6749 which is then posted to generally the same location to retrieve an access token
(this can then also include the refresh token). This access token is I believe what is required to be posted to Niantec, but I'm really not sure on this part (will have to look into another repo). Generally speaking the access token can be used to do any Google call for which you have the scope to do so.
I'll look into it this weekend, in the meantime without having to worry about the entire OAuth flow you could get your access token from https://developers.google.com/oauthplayground/ (use scope profile)
edit
It seems id_token
is a google thing, it should be token
(generally speaking) that you use, I'm not sure on this either.
from poke-api.
I garbled them slightly beforehand but thanks for the precaution :)
Could I use gpsoauth myself to retrieve an access token with the first token?
from poke-api.
JSON Web tokens continue to show information even after slightly garbling them (unless you change quite a lot). Regarding GPSOAuth, I'm not sure, Android has a completely different way of authenticating with Google.
I suppose you could compare the two tokens on https://jwt.io and see what their payload looks like?
from poke-api.
I see, thanks for the heads up.
I'll try that out.
from poke-api.
I had a quick go at this as well, here's what I got
Android
{
"iss": "accounts.google.com",
"aud": "848232511240-7so421jotr2609rmqakceuu1luuq0ptb.apps.googleusercontent.com",
"sub": "117355651878090214803",
"email_verified": true,
"azp": "848232511240-3vdrtrfdntljf2u4mlgtnnlhnign35d5.apps.googleusercontent.com",
"email": "[email protected]",
"iat": 1470254166,
"exp": 1470257766,
"name": "snip",
"picture": "snip",
"given_name": "snip",
"family_name": "snip",
}
Google OAuth
{
"iss": "https://accounts.google.com",
"at_hash": "8cmdAEc-4lYeIGueFL14MQ",
"aud": "407408718192.apps.googleusercontent.com",
"sub": "117355651878090214803",
"email_verified": true,
"azp": "407408718192.apps.googleusercontent.com",
"email": "[email protected]",
"iat": 1470254218,
"exp": 1470257818,
"name": "snip",
"picture": "snip",
"given_name": "snip",
"family_name": "snip",
"locale": "en-GB"
}
Perhaps the audience/authorized presenter needs to match? Not sure how Niantec are validating. I can't even test anything as every time I login in I get a blank api_url... (for both Google and PTC).
from poke-api.
I got similar results with my payload...
On a side note, how is www.pokeadvisor.com doing google authentication? It redirects me to a get a token that is authorized by Niantic themselves: image
from poke-api.
I would guess that Niantec set their OAuth2 flow to local app instead of web app so anyone could use their address.
This gives you a token back which probably then works when fed in to retrieve an access token.
from poke-api.
It's kind of clunky but I am guessing this is the only way to get a token through the web that validates with Niantic.
from poke-api.
Wow, nice job on the procedure. That would have taken me a while...
I'll take a stab at it right now.
from poke-api.
Works like a charm! Here is the procedure I used:
require 'poke-api'
require 'httpclient'
clnt = HTTPClient.new
body = {
grant_type: 'authorization_code',
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
scope: 'openid email https://www.googleapis.com/auth/userinfo.email',
client_secret: 'NCjF1TLi2CcY6t5mt0ZveuL7',
client_id: '848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com',
code: "xxx",
}
uri = 'https://accounts.google.com/o/oauth2/token'
response = clnt.post(uri, body)
body = response.body
hash = JSON.parse body
token = hash["id_token"]
client = Poke::API::Client.new
google = Poke::API::Auth::GOOGLE.new("username", "password")
google.instance_variable_set(:@access_token, token)
client.instance_variable_set(:@auth, google)
client.instance_eval { fetch_endpoint }
I was wondering though, is there any way to do this without having to get the code manually?
from poke-api.
It is possible but it's going to be really hard to explain how, you basically have to 'spoof' being an actual user logging in while saving cookies and all that. HTTPClient can do all of this for you, but it'll be a lot of trial and error. Google Chrome's developer console (network tab) should be a great deal of help here too.
I found this https://github.com/ernilos/PokemonGoApi/blob/4adfa7a891940156193aa6997ceb9fcd895a2f65/PokemonGoApi/AuthenticationService.cs which will hopefully explain the process.
from poke-api.
Thats a pretty hacky solution X_X. Well now that I know that it is possible I am going to close this issue.
from poke-api.
It might just be easier requesting the user to provide you the token, saves a lot of trouble and you get a re-usable refresh token you can store somewhere in your DB for that user to generate the access token indefinitely.
from poke-api.
In case anyone is interested, this https://github.com/kddeisz/poke-go-ivs encapsulates the google login business and shows you the IVs locally.
from poke-api.
👍
from poke-api.
Related Issues (20)
- Does not re-set api_url HOT 5
- syntax error in gpsoauth HOT 1
- Adding proxy support to HTTPClient HOT 7
- Encryption HOT 5
- Is it possible to set the location to a specific latitude and longitude? HOT 1
- Revamp README into a proper Wiki HOT 1
- get_map_objects always returns with empty pokemon arrays HOT 5
- Trying to understand fetch_ticket HOT 7
- Whats the difference between wild and catchable pokemons? HOT 11
- Locating pokestops
- Update signature and allow custom data HOT 6
- Getting unknown type: size_t input_size HOT 1
- Unkown proto fault when using @client.call or @client.login method HOT 8
- gpsoauth is not compatible with ruby 2.0.0 HOT 16
- undefined method `to_h' for [["error", "invalid_grant"]]:Array HOT 6
- Create a chat at Gitter? HOT 2
- 403 HOT 2
- Any chance of a 0.43.x API update? HOT 2
- S2 geometry library porting HOT 1
- wrong S2 cell ID for given latitude and longitude HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from poke-api.