Get Jwt Payload from Google Sign-In without default Google popup - asp.net

I'm trying to use Google Sign-In from my web application (asp.net vb.net).
Following the tutorial that Google provides, and using Google API libraries for .NET this is an easy task.
https://developers.google.com/identity/sign-in/web/sign-in
Now the result of this approach is that I check on the client for a googleUser.getAuthResponse().id_token which is a JWT and send this to my server side code with ajax for validation and to get the payload with the Google unique user Id and other infos.
All this happens on the same page, with a popup from Google, triggered by the default button they provide in the tutorial.
What I'm trying to accomplish is to obtain the same JWT (id_token) without the popup, but actually issuing a redirect to Google, when the user clicks on a custom "Log in with Google" button.
Sadly all the example I found, even from Google itself, involve a much more complex interaction where you get a code from the server, that you then have to exchange for temporary and refresh tokens, and so on.
While the client side approach with the popup window they provide, gives you immediatly the JWT token in response, not that code to request the token, that you have to validate then (I do this with Google .Net APIs with GoogleJsonWebSignature.ValidateAsync(externalToken) and retrieve the payload that way).
Looking at the urls in the popup, what I noticed that differs from all the examples I found that serve you the "code" for token exchange, are those parameters: flowName=GeneralOAuthFlow and response_type=permission%20id_token
While the examples you find for server to server transaction all include calling Google with response_type=code
I tried tampering a bit with the popup url to let it open in a new full window, copying and modifying the url but with not much success. I'm redirected but without the id_token parameter.
Any hint would be much appreciated since I'm not able to find any documentation on response_type=permission%20id_token to query Google service.
Thanks in advance

For anyone interested... I found a solution. The url to redirect to is:
https://accounts.google.com/o/oauth2/auth?response_type=id_token&redirect_uri={0}&scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile&client_id={1}&state={2}
Where
{0} is the redirect url on your server, registered inside google console for this client_id
{1} is your Google client_id
{2} is some querystring or variable you want back to your server when the redirect happens
It works... it gives you back directly the id_token that you can verify with Google .NET APi with GoogleJsonWebSignature.ValidateAsync(id_token) and get as a result a payload (you have the payload class in Google Api .NET as well).
Only issue is that when Google comes back to your redirect url with the id_token in the querystring, it uses hash (url fragment #) so nothing is passed to the server.
There are workarounds with js to get the value and send to the server with ajax or redirect to the same page replacing the hash with ? but this is very annoying.
I imagine there are serious security reason for google to do this but from a dev standpoint is really a pain.
Instead of all those hacks i resorted to the longer way requesting response_type=code instead of the id_token, which returns a canonical querystring with ?code=...
If anyone knows how to get beck the id_token without the hash in the url it would be great.

Related

Failed to refresh Access Token when using Google OAuth2.0 credentials

I am trying to use GA4 API (with Google Python Client & Google Analytics Data Python Client) of Google with the Credentials authentication:
credentials = Credentials(
token=config['access_token'],
refresh_token=config['refresh_token'],
client_id=config['client_id'],
client_secret=config['client_secret'],
token_uri="https://accounts.google.com/o/oauth2/token",
scopes=['https://www.googleapis.com/auth/analytics.readonly']
)
This is working when my access token is not expired. However, this access token is expiring after 1 hour and I want to refresh it via following method:
credentials.refresh(google.auth.transport.requests.Request())
However, this code is returning "invalid_grant" error.
For that problem, I checked almost everything suggested (i.e. system clock/ntp, user permissions, etc.) however I couldn't fix the problem.
Also, I can't figure out about the refresh_token that I use is valid for Google Analytics 4 or not.
So, the questions are:
How can I able to solve this problem?
How can I assure that the refresh_token is valid for GA4?
If not valid, how can I refresh the refresh_token?
Is there any suggestion on the refresh of access_token, any other method or anything else?
Thanks
In my case, the solution was creating new OAuth client and generate a refresh_token for that account depend on the Google Analytics scope.
For that purpose, after I create the new client, I downloaded the client_secrets.json and run the Complete Example by Google and finally I am able to refresh the token.

simulating login process with recaptcha (generating tokens)

I am trying to access a site that need login credentials and solving a recaptcha v2, I am using python requests library to do that.
I am using the anticaptcha api to solve the captcha, and I now have the "g-recaptcha-response", but when I get to the login request, using regular browser and network tab in the DevTools, I see the login request has payload with 2 extra tokens (beside other static data like username and password,..)
these tokens are:
__RequestVerificationToken
RecaptchaToken
__RequestVerificationToken (1yvl3JbNqqll88O3pg7-Qdn8_QC8hcQdUIyCLaAno7xNCg2ql-rycdgC75Xz1AKRlghiuOzE_XZOrJiBTUz25cLOf1M1)
RecaptchaToken (03AOLTBLT9huh3hlzUWneKS-LDVRr0U4_4N8OvsV2dAY6L-DduwTXTdHGFEaLJKzqyNW6w3SAFoKo_hQWq2qecRTsca0IrTYR0pExziAh4eWsDjCj-NdhwBnaVQwo97QaE6q0aKZAIMNx6efET9869Jv_x75KRZX9esLxVY0VT_Zo93ha-iX_4B7h1Si9aicVi59ldaCrCTCClb7SkAw7fYnf_0s1_uY1BfpkcylvHgoGeGXLUdJ91kn_wV0b2USCRkeFb8m9AAS5Cy6avDllc4cmZ8oDH5c9KedQ1kv3Tt03K0-q_4V3BRy0zPV25L6h7qt4PTqT9kRRIQfMI_AvoNbn78kD8mXAJNA)
what are those extra tokens? how I get them?
I searched in all process loaded while solving the captcha in the browser, no mention for these values or even the arguments names.

How do I return an auth token to the google assistant using a website?

I want to implement an Actions for Google app that links to user account in a Firebase project and query's their data. I have a website that is set up using Firebase UI that logs them in and redirects them to a dummy page that basically just says "You have been logged in." I cannot see any documentation anywhere that shows how to return this auth token to google so the assistant can use it to query things on their account. Does anybody know how to accomplish this? I am using this documentation https://developers.google.com/actions/identity/google-sign-in-oauth?creation=no. This is the specific text I am not understanding.
"Your service creates an access token and returns it to Google by redirecting the user's browser back to Google with the access token attached to the request."
This basically means that, instead of returning a new page, you issue an HTTP redirect to a URL that they have sent you as part of the request. You will need to add some parameters to this URL that include the auth info, and this is how Google will get the information - via the redirect handled by the user's browser.
They provide some details further down in step 4 on that page, which reads
Send an HTTP response that redirects the user's browser to the URL
specified by the redirect_uri parameter. Include all of the following
parameters in the URL fragment:
access_token: the access token you just generated
token_type: the string bearer
state: the unmodified state value from the original request
The following is an example of the resulting URL:
https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID#access_token=ACCESS_TOKEN&token_type=bearer&state=STATE_STRING

How to know if user is authenticated on the first request with firebase

Given a backend wrote in nodejs that returns a page that should either link to login (if the user is not logged in) or a link to logout (if the users is already logged in).
Considering I'm using firebase as authentication tool, how can I know in the first request, when the user is accessing the website, if is he authenticated to then
set the ejs template to respond with the correct link ?
Is there some header, or token that can I use ?
The only solution I found was use ajax after the server response, but I don't like this solution because apparently there is a delay in the link renderization.
As far as I know there is no way to know if the user is authentication on the initial request. From a quick inspection no data is sent along with that request. That kinda makes sense, given that upon this request it is not even known if you're using authentication to being with.
Update
I actually just ran into this blog post from one of the Firebase engineers, which seems promising: Introducing session cookies for server-side web apps. I haven't fully read it yet, but the title sounds like it may be exactly what you want.

OAuth 2 Callback Code

I am working on a WordPress plugin that requires the use of OAuth 2. So far I've included the necessary OAuth files in an include folder in my plugin, put in the ClientId, ClientSecret I've obtained, and was able to authorize the app. After I authorized the app I received a callback code that I am supposed to use to get the token I assume. I put that code in my plugin, refreshed the page, and saw the information that is supposed to be outputted. When I go to a different page, it tells me that I am not authorized to view the information because the access token may be missing. So essentially it feels like the code that is sent to retrieve the token is only able to be used once. Do I need to store the token somehow? Any suggestions would be greatly appreciated.
In OAuth2 three-pass procedure the auth_code must be used only to obtain the access token
invoking a specific URL of the authentication server. The access token obtained can be used to access the pages later, as long as it is valid.

Resources