How to refresh id_token from Google OIDC service? - google-oauth

I am building an SPA application (react.js based) that needs id_token issued from Google, and I need to refresh it when the initial id_token is expired because the id_token is used / checked in the backend of my application.
I am reading Google OIDC's instruction, https://developers.google.com/identity/protocols/oauth2/openid-connect, but I did not find a recommended way to get new Google id_token without forcing users to go through sign-in page (which is for sure an unpleasant experience for the users)
How should I achieve the above id_token refreshing? Thanks

It depends on the used flow, but I believe you are using Authorization Code flow with PKCE, so you should to have also refresh token, which can be used for token refresh. Doc: https://developers.google.com/identity/protocols/oauth2/openid-connect#refresh-tokens

Related

How to "sign in with Google" (id_token) *and* receive a code/access_token for specific scope (for the backend)

I'm building an application where a user should be able to sign in with Google, but afterwards, the backend server needs access to some data from the users's account (analytics.readonly scope).
If I understand it correctly, this can be done with the "OAuth Hybrid Flow": An id_token and an authorization_code are returned on the front channel, but the sensitive access_token and refresh_token can only be retrieved on the back channel.
Yet, Google does not seem to provide this functionality.
I imagined that my frontend could receive both an id_token and a code as URL parameters after the Google OAuth flow. The React frontend would then POST both the id_token and the code to my Flask backend.
The backend would then 1) check the id_token, 2) exchange the code for a refresh/access token and return an authenticated session cookie to the frontend.
Now my question:
Can I use just the returned authorization_code to sign in my users? (i.e. instead of an id_token?) What are the security implications? In that case I could just continue with the regular Authorization Code Flow on the backend.
Is there a way, to retrieve both an id_token and an authorization_code from Google at the same time that I have not found?
Is there any other way to achieve what I want? (Sign in with Google for Frontend, secure retrieval of access_token/refresh_token that only the backend needs)
Thanks!
I would handle the token management on the backend instead of doing it in the frontend.
The authorization code is only used as part of the authorization code flow.The code is just a random token and does not contain any user info, so you can't use it to signin the user.
You can't get the id_token and authorization_code at the same time, why would you? Auth code flow is a two step process, so you always get a code first, that you then can exhange for the id/access tokens.
I would consider looking at this this great video for how to approach authentication for SPA applications.

OAuth2 flow in full-stack NestJS application

Yet another OAuth2 question that isn't quite covered elsewhere.
I'm using NestJS backend, React frontend, Passport and my own DB for authentication. Trying to add an
OAuth2 identity provider (Google).
I configured my NestJS app as an OAuth Client. After logging in I'm receiving the callback at which point I have an access_token and the requested user details extracted from the payload of the id_token. This is encapsulated in a class extending PassportStrategy(Strategy, 'google') and an AuthGuard('google') and much of it is handled automatically. Code here.
At this point however, I need to maintain an authenticated session between backend (NestJS) and frontend (React). I suppose I need a JWT, but I'm wondering about the best approach:
Can I use a token provided by the IdP (e.g. id_token or access_token)? So that I don't have to worry about issuing tokens myself. I.e. the frontend receives the token (either from backend, or the IdP directly), sends it on every request, backend verifies it with the IdP on every request (verifyIdToken or getTokenInfo of google-auth-library).
One drawback here is the extra network request every time. I'm not sure if there's a need for that because the IdP is only used to identify the user, not for access to other resources. Another drawback is that I need to store a refresh token and handle when the token expires (get new one, update it on the frontend).
So alternatively, could I just issue a JWT myself and not worry about checking in with the IdP? Once the JWT expires I'd need to prompt the user to log in again. In this case, I wouldn't need to store the IdP tokens. But is this good practice? One issue I can think of is that I won't detect if the user revokes access in the IdP (until the JWT expires).
I ended up issuing my own JWT tokens and managing User sessions in my app, as described in this article: OAuth2 in NestJS for Social Login (Google, Facebook, Twitter, etc)
probably my solution would be helpful.
you could access complete source code of my app that implemented with react typescript (redux toolkit rtk Query) and nestjs included of google oauth2 flow with passport.js. resource

Google Sign-in: Token Expired

I am using google sign-in to allow users to sign-up for my website. The issue I'm having is that my sign-up process is quite lengthy (could take more than 1 hour), and I don't send any information to my backend before the end of the sign-up. However, my the google token expires after 1 hour. I want to avoid the client having to send more than 1 request to google for authentication.
Is there any way to exchange this token for a long-lived token on the backend? I know facebook oauth offers that functionality.
Is there any way to exchange this token for a long-lived token on the
backend?
No, using the referenced article.
Yes, if you also request the Refresh Token during authorization with Google. This requires that the OAuth Flow runs on your webserver.
The Refresh Token can create (request) an Access Token when required. Therefore you don't care about how long your backend takes.
You cannot do the reverse: request a Refresh Token from an Access Token.

REST API Authentication (maintaning an authenticated state)

I am developing a REST API. Currently I am trying to make it minimally secure. I am asking this question because most of the posts I found about this subject were quite old.
For authentication I found this schemes:
Basic authentication
AWS authentication protocol
OpenID
OpenID Connect
OAuth pseudo authentication
Basic Authentication and AWS authentication maintain the requests authenticated after a firts authentication because they keep sending signed requests.
I don't understand how the OpenID and OAuth authentication maintain a (second) request autehnticated? Do I need to check the access token with the OAuth/OpenID server per each request? How does this protects the REST API from receiving requests that have been altered?
Any other schemes that you recommend, advices or reading material about the subject are always welcome.
I'd talk about OAuth here
i) You create a web app and want to use google's OAuth API's.
ii) You register your app here and get credentials.
iii) Now, in the app you'd use Google's SDK to open the login page, enter your credentials and Google would verify it and send you access tokens and refresh tokens.
iv) You would make REST call to google's APIs with the access token and fetch user's data.
Now, coming to the question you asked -
An access token generally lives for 1 hour. Yes, any authenticated calls that you need to make to any of Google's API within one hour could be made with the same access token.
There is another type of token - the Refresh Token. At any time, your app can hit the provider's token exchange endpoint and exchange the refresh token for - refresh token + access token pair.
Now again, you have an access token that will help you for one hour and a refresh token that can be exchanged any time.
Refresh tokens live for as long as you want, till the time the user explicitly revokes permission to your app. (Tells Google that it doesn't not want you to access his resources!)
OAuth would make your REST API secure by ensuring that only authenticated and authorized clients can hit your API. But generally, OAuth is only used when there's a situation where a third party client needs access to a user's resource!

What is the function of Twitter's verify credentials API?

I just implemented sign in with twitter for my webapp. At the end of the OAuth 3-legged flow, I needed to retrieve the screenname & avatar pic for the user. All I had was the twitterid e.g. 3546735
So I performed a GET http://twitter.com/users/show/3546735.json
No security is required for this method, although it is rate-limited.
Recently I've read about another api method called verify credentials
Why should I call this compared to the simple GET above ?
One use of account/verify_credentials for OAuth is it gets the logged in users profile information without affecting the rate limit.
Update: verify_credentials now counts against the users rate limit.
It's of little use to you since you're already doing OAuth. It would provide the credentials in a single request, which can be easier to implement in some applications. Stick with OAuth if you've already done the work.
I believe the verify credentials approach is being phased out. OAuth seems to be the preferred approach.
I felt the need to reply to this and contribute since I've been working and have struggled with the twitter oauth api.
in short verify credentials returns the authenticating users' profile given their access token and token secret.
the reason for this is because in oauth 1.0a flow; after the user completes authentication, twitter sends an oauth_verifier token to you which is used to exchange request tokens for access and token secrets. At this point you do not know the user but have their credentials(access token and token secret). You can verify credentials to identify the owner of these tokens.