I am trying to use an auth code generated from the Javascript Client to then get access and refresh token. But when i call
$client->fetchAccessTokenWithAuthCode($code);
with a code generated on javascript I do not get the tokens. Is there a way to implement this so a redirect approach is not required? Redirects are really dirty and just not elegant and complex to handle for one page apps.
It sounds like you want to pick one auth flow and stick with it. So to pick the right one let me ask you some questions:
Are you trying to use over the air installs?
Are you trying to interact with the My Business API via JS in the browser and via PHP on the server?
Are you trying to persist auth between requests to your single page JS app?
Are you trying to use over the air installs?
R: No credentials over the air (it looks like app specific but mine is a web app)
Are you trying to interact with the My Business API via JS in the browser and via PHP on the server?
R: Yes, acquire a type of temporary authentication that i then pass to the PHP backend (ie the refresh and authentication tokens) such that i can interact with the API on behalf of these user offline.
Are you trying to persist auth between requests to your single page JS app?
R: Yes, the user has a settings panel to authenticate and configure the resources to use. At this point I see Google architected the authentication with the logic of an access code to convert into auth and refresh tokens. The app then renders also when the user is not authenticated for other public users. I just would like to avoid polling or redirects. Other Oath2, flows for instance are browser embedded, no redirect, once a user is authenticated the JS SDK handles the return of the user with its authentication information or a failure if the user does not accept permissions.
hi, do you think the above is feasible? Any further info you would like from me?
I don't think you want to swap credentials between apps like that.
@LindaLawton any ideas?
@mattwhisenhunt I always assume some best practices are used and that an object fetched from an API , a DTO, is consistent across different interfaces of the same API (either this being the JS or PHP one). A redirect is not possible in my app. Also polling a different context (for instance checking my backend while waiting for the credentials to be fetched on a separate iframe) feels extremely dirty in 2018. There must be a better way. I hope you guys see where I am coming from.
Thanks for your feedback.
Hi @mattwhisenhunt why was the issue closed?
Hi @mattwhisenhunt why was the issue closed?
Im having the same issue, in fact this should be possible to do as shown in the official sign-in documentation: https://developers.google.com/identity/sign-in/web/server-side-flow
There are examples for the java sdk and the python sdk. The php sdk does not seem to comply and looks hardcoded for the redirect approach.
@nukkerone maybe open your ticket, it looks like they got upset with my comments. Maybe they will reply to yours with an actual answer
Hi @bizmate and @nukkerone! I saw this comment open up on this closed thread. Seems like a legitimate issue, I'm not sure why it was closed, but let's see if we can figure it out!
The Google_Client::fetchAccessTokenWithAuthCode or Google_Client::authenticate sounds like it should do what we want here. @bizmate - Can you walk me through what's happening?
Following the function, it appears to instantiate the OAuth2 Service, sets the authorization code on the service, and attempts to fetch the Auth Token. It looks like the call should use the correct authorization_code grant.
@bizmate - It might be helpful to step through debug parts of that result?
@danielgsims thank you for re-opening. I will try to explain my understanding with further details.
The PHP way is to ask users to open the dialog where they authenticate and then the auth code is provided back to php. This is achieved with redirects so when the user connects he/she is sent away from the site and then redirected back when the app is authorised.
So assuming the happy path is followed, thus the user has allowed the app access:
Google_Client::fetchAccessTokenWithAuthCode with ->setRedirectUri('http://MyAppService/code')The problem is that the original app page is a module in a dynamic page where an entry point (so the returning redirecting URL) cannot be implemented. Example, MyAppService is embedded in site SomeOnlineBusiness.com . On SomeOnlineBusiness.com I cannot define an entry point, like
SomeOnlineBusiness.com/myAppServiceGoogleAuth because my app could be rendered with an Iframe and this information is not passed down to the iframe. Also I dont want to disrupt the original page on SomeOnlineBusiness where the user is waiting for authentication with redirects.
Alternative, what I would like to achieve instead, Javascript does a similar thing where the auth code is generated within the same javascript context. I tried to get the auth code from MyAppService in Javascript but when I use it in PHP it fails getting the access and refresh codes.
The above is the overall description and I hope provides all the information required.
I can start sharing further code snippets if required.
First off JavaScript dosent return a refresh token. JavaScript uses an implicit login type.
Second using a refresh token that was generated by one client will not work with another. so no you can't swap tokens between clients
example: login php app send refresh token to c# backend service with not work as you will be using two different client types
Now that being said there is some magic in the Android SDK that allows for this.
third Oauth is not intended to work with an iframe I will be very surprised if you get a Google login screen to show in that. you should always open a browser window so the user can see the URL and not be tricked into logging into a fake site.
Hi @LindaLawton
To clarify, I have never said that Javascript does return a refresh token
Javascript does a similar thing where the auth code is generated within the same javascript context
GoogleAuth.grantOfflineAccess(
{
scope: 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.business.manage https://www.googleapis.com/auth/plus.me openid email profile'
} ).then( function(resp){
var auth_code = resp.code; console.log("AuthCode:" + auth_code)
}
)
Above is largely based on https://developers.google.com/identity/sign-in/web/reference#googleauthgrantofflineaccessoptions
Can an auth code generated from JavaScript be used in the php call below?
The JS example works on my machine but I am wondering if what is mentioned there as auth_code is the same as per wording in the php client and then thus I can use it to exchange it with the access code?
It might be confusing but as far as i understand the exchange is
This is code is step 2 above
$client->fetchAccessTokenWithAuthCode($code);
$accessToken = $client->getAccessToken();
It is interesting you just said refresh token that was generated by one client will not work with another (and makes sense because JS can just pop the end user for an access token), but this is not what I am trying to achieve.
last I knew it was not possible to get a refresh token from client side JavaScript code.
Authorization code - life time around five minutes used in hybrid authorization flow. can only be used once to get the first access token and refresh token
authorization code, access token and refresh token are all generated based upon the client id , client secret and the user logging in. This is why I don't think you will be able to mix them.
I also don't think this question really belongs here I think you would be better off taking it to stack overflow and reading the rfc for Oauth2.
last I knew it was not possible to get a refresh token from client side JavaScript code.
As I already mentioned this is not what I am doing or what I am trying to do. I just need to know why the auth token from JavaScript is not working in the PHP client.Authorization code - life time around five minutes used in hybrid authorization flow. can only be used once to get the first access token and refresh token
This is perfectly fine, I just want to pass this from Javascript to my server and use it instantly in PHP to fetch access and refresh token. This is what is failing right now
authorization code, access token and refresh token are all generated based upon the client id , client secret and the user logging in. This is why I don't think you will be able to mix them.This is not a problem, I am using the same client id, secret and handling that same single user interaction in both PHP and JavaScript
I also don't think this question really belongs here I think you would be better off taking it to stack overflow and reading the rfc for Oauth2.
I would not have opened this ticket if this was not specific to this client, but please close it if you really think this is the case. If you do close it please confirm the why too for the benefit also of any reader.
Oauth2 specifications do not force or expect redirects as a solution and I am trying to work around this as it breaks user experience as detailed above.
This is basically the line that is failing at https://github.com/googleapis/google-api-php-client/blob/master/src/Google/Client.php#L192 as it gets no access_code with the auth token from JavaScript. I am really unsure how to proceed. I will have to try further and see what I am missing but as far as I can see everything should be matching, client configuration (id, secrets or api key are about the same account), permissions etc.
If you have any idea please let me know
After reading through this @bizmate, it looks like you鈥檙e just trying to mix incompatible solutions. I didn鈥檛 realize you weren鈥檛 obtaining a compatible token in your original request. We鈥檙e not able to change the OAuth workflow to accommodate your request. I hope this cleared anything up!
@danielgsims @LindaLawton thank you for your replies. It is a shame the token from JavaScript does not work in the PHP side. This forces the use of redirects and they are very bad for user experience.
All other solutions on Oauth based authentication I use or ever publish is always based on a solution that never relies on redirects
FYI, see how Facebook (Graph API) provides the Login/Connect facility through Javascript SDK and then you can just use the short lived tokens to get permanents tokens with PHP. PHP never gets involved with redirects.
Bye for now
This is basically the line that is failing at https://github.com/googleapis/google-api-php-client/blob/master/src/Google/Client.php#L192 as it gets no access_code with the auth token from JavaScript. I am really unsure how to proceed. I will have to try further and see what I am missing but as far as I can see everything should be matching, client configuration (id, secrets or api key are about the same account), permissions etc.
Sounds to me like your code is wrong put it up on stack overflow we can bring it back here if it is an issue with the library and not an issue of incompatible clients or code. If you are feeding it a refresh token this library should not be asking for an access_code.
Trying to compare Google login to Facebook is not going to get you anything except a headache. Its best to accept that they are two different companies with different security policies for their developers.
Hi, just a quick update with the link to my Stack Overflow question here https://stackoverflow.com/questions/54349749/google-mybusiness-access-from-webservers-without-redirects
Most helpful comment
Im having the same issue, in fact this should be possible to do as shown in the official sign-in documentation: https://developers.google.com/identity/sign-in/web/server-side-flow
There are examples for the java sdk and the python sdk. The php sdk does not seem to comply and looks hardcoded for the redirect approach.