Rleationship between Google Identity Services - Sign In with Google and User Authorization for Google APIs - oauth

I'm studying the Google document on "Google Identity Services" and seem to see two stories. One is called "Sign in With Google" which presents an attractive button where a user can sign-in with their Google account. The other is the Google Identity Services Authorization which grants an access token to make API calls.
What I am missing is whether or not there is a relationship between these two concepts/SDKs/functions. My mind is saying that I want a pretty button on my web page that I can use to sign in (ala Sign in With Google) AND I want the click of that button to give me an access token that I can use to invoke Google APIs. What I seem to be finding is that they are separate and discrete concepts with no obvious relationship between them. Is that correct?
References
Google Identity Services JavaScript SDK - Authorization
Sign in with Google
2022-06-26: Following a post from Blunt, I tried to add a hint but that didn't seem to make a difference. Here is the code I have been using. First, the index.html that loads the test:
<!DOCTYPE html>
<html>
<body>
<script src="https://accounts.google.com/gsi/client"></script>
<script src="./index.js"></script>
<div id="g_id_onload" data-client_id="XXX.apps.googleusercontent.com"
data-callback="handleToken" data-auto_prompt="false">
</div>
<div class="g_id_signin" data-type="standard" data-size="large" data-theme="outline" data-text="sign_in_with"
data-shape="rectangular" data-logo_alignment="left">
</div>
</body>
</html>
and the JavaScript loaded in index.js
const clientId = "XXX.apps.googleusercontent.com"
function handleToken(x) {
debugger;
const client = google.accounts.oauth2.initTokenClient({
client_id: clientId,
hint: "myemailaddress",
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (response) => {
debugger;
},
});
client.requestAccessToken();
}
What I am finding is that I get a the button in the web page as desired ... I click the button, I am prompted to sign in to Google and then the debugger statement (the first one) in the handleToken function is reached. The code progresses and then I am prompted to sign in to Google a second time. It had been my hope that the first sign-in would have been sufficient and somehow context would be preserved for the authorization.

In the new Google Identity Service, the authentication (sign-in) and authorization (access to api's) are separated, but not entirely distinct.
I have an article that explains this, and a reference implementation for pure client-side solution. npm install gothic will get you that reference implementation.
But here are the details:
(1) The sign-in with Google gives you the pretty button. Signing in provides user information encoded in a JWT. But none of this provides an access token.
(2) To obtain the authorization, you need to drive a second, sequential process. To expedite this process you can use the email address from the sign in process as an optional hint parameter to the authorization library, but the first time the user accesses it, they will still need to go through an explicit authorization process, depending on what api's (scopes) you need to access.
With regard to authorization, there are two models:
(1) Token-based. This is the pure client-side version. With this, you ultimately provide your clientId, your API-key, the discovery uri and the scopes to the library, and you get back a 1-hour token, that authorizes use of the APIs your app needs. As I mentioned, this requires an explicit prompt to the user the first time, and is click-free thereafter. But you will need to renew that token every hour, or on each page refresh.
(2) Code-based. This requires you to have a server-side to your app as well. In this model, your client obtains a code from Google, and hands that to your server. Your server exchanges it for an access token and a refresh token, and thereafter uses the refresh token to obtain new access tokens.
The server-side, code-based model is the more secure, and can ultimately provide the better UX, but it is of course more architecturally complex.
If you have specific code you are trying to get working, feel free to share and we can help.

To start with you need to understand the difference between two concepts.
Authentication and authorization.
authorization
Authorization is the act by which a user who owns private data grants an application created by a developer to access their data. Authorization is requested by showing a consent screen. A user consents to the application accessing their data, the amount of access a user grants is designated by the scopes requested.
In the image below the application Google Oauth 2.0 Playground is asking me for permission to See and download all my google drive files.
I requested the "https://www.googleapis.com/auth/drive.readonly" scope when requesting authorization.
Authorization is Oauth2. it returns an access token and a refresh token. Access tokens can be used to access api endpoints. In this case the google drive api. Access tokens are short lived and expire after an hour. The refresh token can be used to request a new access token at any time when the user is off line. This is why there is no way for an api to see if the entity preforming the call is actually the user who owns the data, it may infact be a third party application using an access token and refresh token to gain access to the users data.
You can grant an application access to your data and they can continue to request your data until you revoke that access.
Authentication
Authentication on the other hand is sign in. It is prof that the what made the call is in fact the user who owns the account. They must have typed their user name and password or logged into their account. Or already be logged into their google account on their machine. If you have two google accounts signed in like I do they you will be promoted for which user you would like to use.
So authencation authenticates or proves, that the user making the call is in fact the owner of the account the data resides on. Authentication is something called Open Id connect and was built on top of Oauth2.
The scope that are email, profile, and openid either profile or openid is required email is optional. Open id connect basically gives you access to a users profile information. If you are using a library you wont normally see this scope its normally added internally. If the only scope that is requested is a open id connect scope then the user will not see a consent screen. In the call above I added profile scope so you can see it is also asking for access to profile data but its grayed out the user cant not accept it.
Open id connect returns something called an id token. the id token is very short lived its around five minutes. An id token is a jwt so you can use jwt.io to decrypt it. Within the jwt you can find a number of claims. This claims give your application information about who the user is that just signed into your system.
Of note, name, picture, locale (language), and sub, sub is the users internal user id on the calling authentication server. So you can use the google sub id to link this users google account to your internal user storage. Then when ever this user logs in using google you will know which user it is in your system by matching the id.
{
"iss": "https://accounts.google.com",
"azp": "40740878192.apps.googleusercontent.com",
"aud": "407408718192.apps.googleusercontent.com",
"sub": "1172004532672775346",
"at_hash": "Aa0FT7DLf38T_onVI_ca8g",
"name": "Linda Lawton",
"picture": "https://lh3.googleusercontent.com/a-/AOh14GhroCYJp2P9xeYeYk1npchBPK-zbtTxzNQo0WAHI20=s96-c",
"given_name": "Linda",
"family_name": "Lawton",
"locale": "en",
"iat": 1656311886,
"exp": 1656315486
}
Note.
Sign-in will not grant you an access token unless you are able to add additional scopes to it, like drive, or calendar. I have yet been able to figure out how to add additional scopes to googles new JavaScript web login library.
The thing is what exactly are you trying to do. Do you want to log a user into your system. Or do you just want access to some private user data of theirs through one of googles apis?

In order to prevent the authorization flow to re-request for authentication, you need to add the prompt and the hint properties to the initTokenClient or the initCodeClient method config object (depending on which one of them you use - see here).
Here is how it looks like:
google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
callback: 'YOUR_CALLBACK',
hint: 'THE_USER_EMAIL',
prompt:''
});
As mentioned, the same is true for initCodeClient.
In the same way, you can pass those properties not only on initialization phase, but on the event phase as well, with the requestAccessToken or requestCode, respectively. Here it is:
googleClient.requestAccessToken({
prompt: '',
hint: 'THE_USER_EMAIL'
});
In this code, googleClient is a JS const that stores the Google codeClient / tokenClient object.
Explanation:
The prompt parameter with empty string tells Google to not request authentication if the user is already authenticated. This will let the flow to continue right to the authorization phase.
This is not enough, because if there is more then one account connected to the browser, Google can not decide to WHICH one of them he should ask for authorization API. This situation will cause the authentication popup to show again, in order to let the user to choose an account.
This is where the hint parameter comes to play, it lets Google to know what accont to use, then, if this account is already connected, Google is able to pass the entire authentication popup and go right away to the authorization one.
In order to get the user email, you should use the credential property, returned from the authentication API of google.accounts.id.initialize. This credential is a JWT string, after decoding it with the JS atob method, you'll be able to extract the user email from it, beside other properties. For more details regarding to this, please check here.

Related

How do you implement the new DocuSign OAuth2.0 SOBO using eSignature SDK?

I'm in the process of converting an internal C# API that uses a legacy SOBO integration to one that uses OAuth 2.0 as required by DocuSign. The legacy application makes all requests to DocuSign using DocuSign credentials of an application user (a non-person) and injects SOBO data (email address) in the appropriate header when we need to generate an embedded sending URI and have it appear that the envelope was sent by a real person without using their credentials.
I have successfully converted another (non-SOBO) internal API using JWT grant, but I do not know how replicate the SOBO dependent workflow. Have read Matt King's article "From the Trenches: OAuth 2.0 and the new SOBO", but still a bit confused. I know how to extract userId from email address as mentioned in the article, but not sure what do with it. Similar to my legacy application, I am using a application user to get consent and ask for JWT token without prompting internal users for their consent. Is this still possible using OAuth 2.0?
Happy to help here. Once you've retrieved the user's apiUserName / userId you'll want to add it into the JWT assertion's sub line.
When you go to generate the token, if consent has not been provided by or for the user, our system will send back an error of "Consent_Required." See https://www.docusign.com/blog/developers/oauth-jwt-granting-consent for different methods of granting consent.
For individual consent, the user needs to go to a specific URL containing your clientId, redirectUri, and some additional scopes. If they hadn't previously consented to the scopes in your OAuth request they will be prompted to do this once. You can confirm consent has been applied by having them visit the same link afterwards, which will send them directly to your redirectUri.
Domain consent works a little differently -- you need to have an organization, a claimed domain, and the users you're providing consent on behalf of need to have an email address that is part of that claimed domain.
Happy to connect and walk you through it -- if you can open a ticket at support.docusign.com and in the details request they reach out to me I should be able to have the case transferred and work with you from there.
Regards,
Matt King

How to implement OpenID Connect authentication with 3rd party IDPs in a microservices architecture

For the past 10+ days I've read an watched ALL the content I could find on understanding OAuth2 and OpenID Connect, only to find that many people disagree on the implementation, which really confuses me.
To my understanding, all the articles and examples I found assume you want access to eg. google calendar, profile info or emails if you eg. login with google, but I do NOT need to access other than my own API's - I only want to use Google, Facebook etc for logging in, and getting an id which I can link to my user in my own database - nothing more than that.
I'll try illustrate my use case and use that as an example.
A note on the diagram: the Authentication service could probably be built into the API Gateway - not that i matters for this example, since this is not about "where to do it", but "how to do it the best way" possible, for an architecture such as mine, where it's used for my own API's / Microservices, and not accessing Google, Facebook etc. external API's
If you can understand what I'm trying to illustrate with this diagram above, please tell me if I've misunderstood this.
The most basic requirements for this architecture you see here are:
Users can login with Google, Facebook, etc.
The same login will be used for all micro-services
OpenId user will have a linked account in the database
User access is defined in my own db, based on groups, roles and permissions
I do not intend to use external API's after the user is authenticated and logged in. No need for ever accessing a users calendar, email etc. so I really just need the authentication part and nothing else (proof of successful login). All user access is defined in my own database.
So a few fundamental questions comes to mind.
First of all, is OpenID Connect even the right tool for the job for authentication only (I'll have no use for authorization, since I will not need read/write access to google / facebook API's other than getting the ID from authenticating)?
People generally do not agree on whether to use the ID or Access token for accessing your own API's. As far as I understand the ID token is for the client (user-agent) only, and the access token is for eg. accessing google calendar, emails etc.... External API's of the OpenID Provider... but since I'll only be accessing my own API's, do I event need the access token or the ID token - what is the correct way to protect your own API's?
If the ID token is really just for the client, so it can show eg. currently logged in user, without going to the DB, I have 0 use for it, since I'll probably query the user from from the db and store it in redux for my react frontend app.
Dilemma: To store user details, groups, roles and permission inside JWT or not for API authorization?
By only storing the user identifier in the token, it means that I always allow authenticated users that has a valid token, to call endpoints BEFORE authorization and first then determine access based on the db query result and the permissions in my own database.
By storing more data about the user inside the JWT, it means that in some cases, I'd be able to do the authorization / access (group, role, permission) check before hitting the API - only possible with user info, groups, roles and permission stored inside a JWT issued upon login. In some cases it would not be possible due to eg. the CMS content access permissions being on a per-node level. But still it would mean a little better performance.
As you can see on the diagram I'm sending all API requests through the gateway, which will (in itself or with an authentication service) translate the opaque access token into some JWT with an identifier, so I can identify the user in the graph database - and then verify if the user has the required groups, roles and permissions - not from an external API, but from my own database like you see on the diagram.
This seems like a lot of work on every request, even if the services can share the JWT in case multiple services should need to cross call each other.
The advantage of always looking up the user, and his permissions in the db, is naturally that the moment the user access levels change, he is denied/granted access immediately and it will always be in sync. If I store the user details, groups, roles and permission inside a JWT and persist that in the client localstorage, I guess it could pose a security issue right, and it would be pretty hard to update the user info, groups, roles and permissions inside that JWT?
One big advantage of storing user access levels and info inside the JWT is of course that in many cases I'd be able to block the user from calling certain API's, instead of having to determine access after a db lookup.
So the whole token translation thing means increased security at the cost of performance, but is is generally recommended and worth it? Or is it safe enough to store user info and groups, roles, permissions inside the JWT?
If yes, do I store all that information from my own DB in the ID Token, Access token or a 3rd token - what token is sent to the API and determines if the user should be granted access to a given resource based on his permissions in the db? Do I really need an access token if I don't need to interact with the ID providers API? Or do I store and append all my groups, roles, permissions inside the ID token (that doesn't seem clean to me) issued by OpenID connect, and call the API and authorize my own API endpoints using that, even if some say you should never use the ID token to access an API? Or do I create a new JWT to store all the info fetched from my database, which is to be used for deciding if the user can access a given resource / API endpoint?
Please do not just link to general specs or general info, since I've already read it all - I just failed to understand how to apply all that info to my actual use case (the diagram above). Try to please be as concrete as possible.
Made another attempt to try and simply the flow:
The following answer does only apply for a OpenID Connect authentication flow with a 3rd party IDP (like Google). It does not apply for an architecture where you host your own IDP.
(There are some API gateways (e.g Tyk or Kong) which support OpenID Connect out of the box.)
You can use JWTs (ID token) to secure your APIs. However, this has one disadvantage. JWTs cannot be revoked easily.
I would not recommend this. Instead you should implement an OAuth2 authorization server which issues access tokens for your API. (In this case, you have two OAuth2 flows. One for authentication and one for authorization. The ID and access token from the IDP are used only for authentication.)
The following picture shows a setup where the API gateway and authentication/authorization server are two separate services. (As mentioned above, the authentication/authorization can also be done by the API gateway.)
The authentication flow (Authorization Code Grant) calls are marked blue. The authorization flow (Implicit Grant) calls are marked green.
1: Your web app is loaded from the app server.
2a: The user clicks on your login button, your web app builds the authorization URL and opens it. (See: Authorization Request)
2b: Because the user hasn't authenticated and has no valid session with your authorization server, the URL he wanted to access is stored and your authorization server responds with a redirect to its login page.
3: The login page is loaded from your authorization server.
4a: The user clicks on "Login with ...".
4b: Your authorization server builds the IDP authorization URL and responds with a redirect to it. (See: Authentication Request)
5a: The IDP authorization URL is opend.
5b: Because the user hasn't authenticated and has no valid session with the IDP, the URL he wanted to access is stored and the IDP responds with a redirect to its login page.
6: The login page is loaded from the IDP.
7a: The user fills in his credentials and clicks on the login button.
7b: The IDP checks the credentials, creates a new session and responds with a redirect to the stored URL.
8a: The IDP authorization URL is opend again.
(The approval steps are ignored here for simplicity.)
8b: The IDP creates an authorization and responds with a redirect to the callback URL of your authorization server. (See: Authentication Response)
9a: The callback URL is opened.
9b: Your authorization server extracts the authorization code from the callback URL.
10a: Your authorization server calls the IDP's token endpoint, gets an ID and access token and validates the data in the ID token. (See: Token Request)
(10b: Your authorization server calls the IDP's user info endpoint if some needed claims aren't available in the ID token.)
11a/b: Your authorization server queries/creates the user in your service/DB, creates a new session and responds with a redirect to the stored URL.
12a: The authorization URL is opend again.
(The approval steps are ignored here for simplicity.)
12b/+13a/b: Your authorization server creates/gets the authorization (creates access token) and responds with a redirect to the callback URL of your web app. (See: Access Token Response)
14a: The callback URL is opened.
14b: Your web app extracts the access token from the callback URL.
15: Your web app makes an API call.
16/17/18: The API gateway checks the access token, exchanges the access token with an JWT (which contains user infos, ...) and forwards the call.
A setup where the authorization server calls the API gateway is also possible. In this case, after the authorization is done, the authorization server passes the access token and JWT to the API gateway. Here, however, everytime the user infos change the authorization server has to "inform" the API gateway.
This is a very long question. But I believe most can be summarised by answering below,
To my understanding, all the articles and examples I found assume you want access to eg. google calendar, profile info or emails if you eg. login with google,
You do not necessarily use Access token (ID token in some occasions) to access the services offered by token issuer.You can consume tokens by your own APIs. What these Identity Providers (synonym to Authorization server, or IDP in shorthand) is to hold identities of end users. For example, typical internet have a Facebook account. With OAuth and OpenID Connect, the same user get the ability to consume your API or any OAuth/OIDC accepted service. This reduce user profile creation for end users.
In corporate domain, OAuth and OIDC serves the same purpose. Having a single Azure AD account lets you to consume MS Word as well as Azure AD's OIDC will issue tokens which can be used to Authorise against an in-house API or an third party ERP product (used in organization) which support OIDC based authentication. Hope it's clear now
A note on the diagram is that the Authentication service could probably be built into the API Gateway - not sure if that would be better?
If you are planning to implement an API gateway, think twice. If things are small scale and if you think you can maintain it, then go ahead. But consider about API managers which could provide most of your required functionalities. I welcome you to read this article about WSO2 API manger and understand its capabilities (No I'm not working for them).
For example, that API manager has built in authentication handling mechanism for OAuth and OIDC. It can handle API authentication with simple set of configurations. With such solution you get rid of the requirement of implement everything.
What if you can't use an API manager and has to do it yourself
OpenID Connect is for authentication. Your application can validate the id token and authenticate end user. To access APIs through API Gateway, I think you should utilise Access token.
To validate the access token, you can use introspection endpoint of the identity provider. And to get user information, you can use user-info endpoint.
Once access token is validated, API gateway could create a session for a limited time (ideally to be less or equal to access token lifetime). Consequent requests should come with this session to accept by API gateway. Alternatively, you can still use validated access token. Since you validated it at the first call, you may cache for a certain time period thus avoiding round trips to validations.
To validate user details, permission and other grants, well you must wither bind user to a session or else associate user to access token from API gateway at token validation. I'm also not super clear about this as I have no idea on how your DB logic works.
First Appreciate your patience in writing a very valuable question in this forum
we too have same situation and problem
I want to go through ,as images are blocked in our company in detail
Was trying to draw paralles to similar one quoted in the book
Advance API In Practise - Prabath Siriwerdena [ page 269]Federating access to API's Chapter. Definitely worth reading of his works
API GW should invoke Token Exchange OAUTH2.0 Profile to IDP [ provided the IDP should support TOken Exchange profile for OAUTH 2.0
The Absence of API Gateway , will result in quite bespoke development
for Access Control for each API Check
you land up in having this check at each of the api or microservice [ either as library which does work for you as a reusable code]
definitely will become a choking point.]

Microsoft's REST API's

I am working on integrating Outlook's calendar REST API with my personal system.
Using the authorization code grant flow, I am able to get a user to login to an application that I have registered in https://apps.dev.microsoft.com. Once a user has logged in successfully, I receive a code on my redirect URL. Using the code, I fetch his bearer token (basic oAuth code flow).
Now, the confusion is with their documentation. They have 3 types of API, o365, outlook.office and graph. I am using their graph API for the calendar resource.
I'm using https://graph.microsoft.com/v1.0/me/calendarview to fetch events from the primary calendar, https://graph.microsoft.com/v1.0/me/events to create events in the primary calendar and https://graph.microsoft.com/beta/$batch for batch requests.
There are some scenarios that I want to cover here. When a user changes his/her outlook password, I need the user to re-login to the app so I can use a valid bearer token. From outlook documentation, it looks like the refresh token becomes invalid as soon as the user changes the password (search for refresh tokens become invalid); which means, at the worst case, I can use the bearer token for an hour (default) to authenticate the API's.
Is this normal of an oAuth flow? I always thought the bearer token would become invalid when a user changes the password.
Since I am working in an organization, I want my application to only be accessible by AD users in my organization.The application manifest has a field called availableToOtherTenants, which is defaulted to true. I changed the field to false so that only the users belonging to the organization AD can access it. But it looks like I am able to login to the application with my personal outlook account as well; in spite of this change.
What am I doing wrong here? Am I doing the right this by registering
an application in https://apps.dev.microsoft.com?

Enabling OAuth support in Square Connect

I have an application that currently integrates into my merchant account using my access token. Early discussion with neighborhood merchants indicates some positive interest. I want to integrate OAuth support so that I can try to get traction with those merchants.
Though https://docs.connect.squareup.com/api/connect/v1/#navsection-oauth has information, I seek some additional clarification.
(i) Access using https redirect-url is denied at Square Connect Authorize has an answer "By default the OAuth flow is disabled for applications which is why you are seeing the "Authorization not allowed" failure. If you wish to enable OAuth flow for your application then you need to contact Square." #SquareConnectSupport: I have sent an email to Developer#Square, please let me know what else do I do.
(ii) Here is how I think it will work - the OAuth integration (Please confirm)
User types in browser say "mysnow.com/square"
The Handler at "mysnow.com/square" allows user to type in an ID this ID is local to mysnow
Then the Handler at "mysnow.com/square" directs the merchant to https://connect.squareup.com/oauth2/authorize along with my application id, permissions and redirect url.
The handler then receives a notification code with AuthZ Code at the redirect URL previously provided.
Next the handler obtains the Access token (using the AuthZ code)
Finally, the handler then saves the ID, the AuthZ code , the relevant Access Token and the date/time stamp (when the token was obtained) as a tuple in a safe data store.
(iii) Using the Access Token
When there is need to access merchant data of given ID, then use the ID to get the Access Token. Use this Access Token to manage the permitted data (based on permission)
Renew the access token periodically.
​(iv) For testing purposes, I create few test/dummy merchants?​ Or do you have dummy merchant accounts that I can use for testing.
You can authorize up to ten merchants through the OAuth flow without approval from Square, which should be enough to get your integration running and tested. If you would like to make it more broadly available, you will need to contact Square about getting the app in the Square App Marketplace.
That looks essentially correct. The best practice for OAuth is something like this:
Merchant visits your landing page (e.g. mysnow.com/square) and clicks an action to start using your square integration.
Merchant's browser is redirected to the OAuth page (https://squareup.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=LIST_OF_OAUTH_SCOPES_YOU_NEED)
Merchant authorizes your application to access their data and is redirected back to your site. In the URL is an authorization code
Your backend makes an API call to Square to exchange the authorization code for an access token. It then uses that access token to look up information about the merchant and pre-populate fields of your signup form (e.g. you can get name, email, etc)
With a partially populated signup form on your site, merchant is prompted to complete their registration with your service.
There isn't really a way to create "dummy" merchants, but you can sign up for multiple merchant accounts with the same identity information, as long as you use a different email for each one. If you have GMail, you can do "you+someword#gmail.com" and the mail will be redirected to "you#gmail.com", so you don't need to create a bunch of email accounts to have unique email addresses.

Performing Google Federated Login/oAuth2 after initial Authentication

I am trying to support "Hybrid" Federated Login and oAuth2 (using logic from this document) for a webservice which will:
support Sign in using your Google account on my site. That is, from the documentation: You can also choose to use Google's authentication system as a way to outsource user authentication for your application. This can remove the need to create, maintain, and secure a username and password store.
Access the user's Google Analytics.
Here are the steps I have done.
I form my request to https://accounts.google.com/o/oauth2/auth with the scopes (Google Analytics) I want access to.
I Get redirected to google where it has my icon and which scopes I am requesting access to. I grant access.
I get redirected back to the callback page.
I get the tokens (access and refresh), as well as a huge id_token string (which I don't know) and store all of this information in my database.
I then make a call to https://www.googleapis.com/oauth2/v1/userinfo?access_token=xxxyyyzzz to get the user's email and name and store this information in my database too. I also notice it returns a id field which to my knowledge never changes and I presume is some sort of unique identifier. I store this too.
Question: If I go to Authorized Access to your Google Account section in my Google account, it shows that my site has access to "Google Analytics. BUT, it does not say Sign in using your Google account. This is what I am trying to accomplish. I would have thought using the logic would enable Sign in using your Google account. What am I doing wrong? And what would be the applicable call to google so that users can sign in to my site?
If your site has access to something like your Contacts or Analytics using OAuth, you'll never see "Sign in using your Google account". I'm pretty sure that's only if you use OpenID (not OAuth) only for sign-in.
Specifically, OAuth is used for giving you access to APIs to create/update/delete data, while OpenID is for signing in.
If you are asking how to identify user for future logins, you have two options:
Mix OAuth with OpenID, that is called Hybrid. I have described it on this answer.
Use userinfo scope and request userinfo (email, etc.) after successful OAuth authorization. It is described on Google OAuth 2 documentation.
If you mean automatically login to your web site in future visits you can use OpenID "immediate mode" (openid.mode parameter).
When the user is redirected back, you call the second request from your own (server-side?) code, and get their email address. When you successfully get it, that means that the user is logged on. You can add it to the session (e.g. as cookie), and as long as you have it, the user is logged on. You make the user log out by forgetting the email address, so by clearing the session/cookies.
Add this paramter to the https://accounts.google.com/o/oauth2/auth URL call: approval_prompt=force and then the Sign in using your Google account will always show regardless of whether the user was already signed into that or any other account.
So the call would be like this https://accounts.google.com/o/oauth2/auth?client_id=<client id>&redirect_uri=<uri>&scope=<scope>&access_type=<online or offline>&response_type=code&approval_prompt=force

Resources