In firebase we can use signInWithPopup and get our auth provider access token by credential.accessToken.
We can only get this accessToken one time after login. But this access token is expired in one hour!
And we need to force user to login again to get access token.
What the point of this completely useless access token user experience? If we cant use it anyway.
update:
I'm developing Chrome Extension with Firebase and trying to add Google Calendar support. And I spent already several days but didn't found solution.
first GAPI is not working in Chrome Extension. I tried to use signInWithPopup and make it with REST calls but google.com oauth2 access token in firebase is expiring after one hour and there is no way to refresh it silently.
This is all Google products and why they are so hard to make work together?
update2:
provider = new firebase.auth.GoogleAuthProvider();
provider.addScope('https://www.googleapis.com/auth/calendar.events');
const result = await firebase.auth().signInWithPopup(provider)
var credential = result.credential;
// Saving **credential** somewhere for later use it in REST calls to` https://www.googleapis.com/calendar/v3/users/me/calendarList
PROBLEM this access token is expired after ONE hour.
Related
In my web application I have integrated user Firebase Authentication using Google Sign-in. After successful sign-in Firebase returns AccessToken and RefreshToken. Using this AccessToken I am able to call Google APIs (eg; calendar API).
What I wanted to know: If I store user's RefreshToken in DB, later on (may be after a week or so) application backend can get user's RefreshToken from DB and call some Google API (don't know which and how) to retrieve user's AccessToken. This AccessToken will be used to call Google APIs without any issue.
In short, is it possible for backend to retrieve user's AccessToken by using user's RefreshToken for calling Google APIs?
I cant say i have tried with something that came from firebase auth but in theory it should work
This is the call you make.
HTTP POST https://accounts.google.com/o/oauth2/token
client_id={ClientId}&client_secret={ClientSecret}&refresh_token=[REFRESHTOKEN]&grant_type=refresh_token
Love to hear if it works or not.
I have a web application where users can sign in with Google.
To the sign-in process, I add a scope to be able to access Google Calendar.
Now that the user is signed in, I would like to - in server-side - get their current Google access token in order to make a request and get a list of their events.
Is there a way to get the current OAuth token (no need for refresh token) in order for me to make this completely on the server-side?
I'd say that you can check this article and put special attention to the recommendation for websites.
I understand you have configured already the consent screen, which is the first step of the basic steps on using OAuth 2.0. So I understand that you only have to perform the following steps:
Obtain an access token from the Google Authorization Server
Examine scopes of access granted by the user.
Send the access token to an API
I think you can also give a look to this other doc for more GCP insights over your goal to authorize the request using user tokens
Edited:
Regarding the Firebase Authentication, I understand this happens at the user's device, and you could use some code to retrieve the token and then send it to your back end servers as mentioned in here.
As a sample here there's the sample code for retrieving the token in Android:
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getIdToken(true)
.addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
public void onComplete(#NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
String idToken = task.getResult().getToken();
// Send token to your backend via HTTPS
// ...
} else {
// Handle error -> task.getException();
}
}
});
A little about OAuth 2.0
Whenever a user signs up to your app/website via Google or 3rd Party, an Authorization Code, this Authorization Code is exchanged for an AccessToken & RefreshToken.
The AccessToken sent via Google are valid generally for 60 minutes.
Offline Access (Server Side)
Let's break it down to two parts:
If your need to update within 60 minutes of user's last activity
You can use firebase along with gapi to achieve that. You'll be provided with the AccessToken that can be sent back to server to add to calendar.
More info on implementation
If you need to update after 60 minutes of user's last activity
Firebase & gapi's most method handle the AuthorizationCode flow internally. They even further refresh the AccessToken after 60 minutes. This is beneficial for most developers as they won't have a headache of managing all the tokens.
This method but, hides RefreshToken & AuthorizationCode from the developer. That is even if your server has the access token, it won't be able to refresh it and it would be deemed useless.
To achieve complete offline access, in the initial request to get AuthorizationCode you will need to send a HTTP GET parameter access_type to offline
GAPI provides you with grantOfflineAccess() method which returns the AuthorizationCode that can be later used on your server to fetch access token & refresh token.
Note: If you are storing AuthorizationCode in your database, make sure it is secure. The limitation in Firebase are set due to security reason. It is more secure to not talk with AuthorizationCode generally.
More links
https://developers.google.com/identity/protocols/oauth2/web-server
https://developers.google.com/identity/sign-in/web/reference
https://developers.google.com/identity/sign-in/web/server-side-flow
https://developers.google.com/identity/sign-in/web/backend-auth
Retrieve Google Access Token after authenticated using Firebase Authentication
I am trying to sign in with google using
IAuthResult user = await FirebaseAuth.Instance.SignInWithCredentialAsync(credential as AuthCredential);
then I can get the idToken using
var token = user.User.GetIdToken(false);
but there is no way to get the refresh token to store it in order to check if it is valid or not.
Any suggestion?
You don't actually need to use the refresh token yourself. This is handled behind the scenes from the Firebase SDK so you will remain connected so long as you do not sign out. The tokes expire after one hour but they will be automatically refreshed. You can revoke a refresh token using the Admin SDK. https://firebase.google.com/docs/auth/admin/manage-sessions
In my firebase (Angular) app, I'm using firebase authentication to log a user in via their Google Profile. As part of this process, the user gives me permission to access their gmail account (scope 'https://www.googleapis.com/auth/gmail.compose').
After the user has logged in this way, I want to configure the "gapi" google javascript SDK so that the "signed in user" is the user signed in via firebase auth. Here's where I'm having trouble.
It appears that I need to set the client token for the gapi sdk like so gapi.client.setToken(userAccessToken) and the token needs to be set before the gapi client is initialized. Attempting to do this doesn't seem to work however (a call to gapi.auth2.getAuthInstance().isSignedIn.get() returns false when it should return true).
I also can't figure out a way of changing the "signed in user" if the firebase user logs out and a new one logs in. This is because, again, the gapi client seems to require the gapi.client.setToken() be called before the client is initialized, and I can't see any way of re-initializing and already initialized gapi client.
I can get the gapi client working if I use the gapi client's own gapi.auth2.getAuthInstance().signIn() method, but then the user is asked to sign in to my app twice using (from the user's perspective) identical google login popup boxes (one prompt originating from firebase auth and the other from the gapi client).
Does anyone have any suggestions / tips? After someone logs in via firebase auth I can get access to their userAccessToken, I just can't figure out how to programmatically pass that to the gapi client in a clean way.
Ideally:
on application load the gapi client would also load and initialize.
When a user chose to sign in, I would be able to use Firebase Auth to log someone in via their google profile, then get their access token and pass it to the gapi client to make google api calls.
If the firebase user ever logged out, I would clear the gapi client's api token.
If a new firebase user logged in, I would re-set the gapi client's api token.
I have come upon a placeholder (i.e. non-ideal) solution to this problem by following this S.O. answer.
In short, the GAPI client does not seem to let you manually pass it an access token, but the firebase auth client does let you manually pass it an access token. So, instead of handling authentication with the firebase sdk and passing the token to the GAPI client, you need to do the reverse and handle authentication with the GAPI client and then pass the token to the firebase SDK.
I want users to have access to their Youtube playlists after signing in with Google through Firebase. I use firebase.auth().signInWithRedirect(provider) for signing in and I can get their access token with firebase.auth().getRedirectResult() and everything works perfectly just after they signed in.
The problem is that I can't get their access token back if they refresh the page. Firebase automatically signs them in again but firebase.auth().getRedirectResult() returns
{user: null, credential: undefined, operationType: undefined}
I have tried the method used in Google's OAuth 2.0 Playground but I don't know where to get the authorization code used in step 2.
I'm grateful for any help.
Firebase doesn't provide a way to refresh a Google access token. Perhaps you are better off using Google web sign in SDK to obtain the Google access token: https://developers.google.com/identity/sign-in/web/sign-in
It also refreshes that for you automatically.
You can then pass the Google access token or ID token to sign in with Firebase:
firebase.auth().signInWithCredential(firebase.auth.GoogleAuthProvider.credential(googleIdToken, googleAccessToken));