Scenario: I have an app(gcpapp) running on GCP that is secured with IAP and I am able to connect to an API inside gcpapp with following code.
import 'package:google_sign_in/google_sign_in.dart' as sign_in;
....
final sign_in.GoogleSignInAccount _googleSignInAccount =
await sign_in.GoogleSignIn().signInSilently();
final googleSignInAuthentication = await _googleSignInAccount.authentication;
final FirebaseAuth _auth = FirebaseAuth.instanceFor(app: await Firebase.initializeApp());
result of print(_auth.currentUser);
:
User(displayName: ******, email: *****@gmail.com, emailVerified: true, isAnonymous: false, metadata: UserMetadata(creationTime: 2021-05-27 12:08:06.692, lastSignInTime: 2021-05-28 08:40:47.806), phoneNumber: null, photoURL: https://lh3.googleusercontent.com/a-/**********, providerData, [UserInfo(displayName: *******, email: *****@gmail.com, phoneNumber: null, photoURL: https://lh3.googleusercontent.com/a-/*********************, providerId: google.com, uid: *****************)], refreshToken: , tenantId: null, uid: ********************)
Below code works fine for 1 hour, when JWT is valid.
final response = await http.post(
Uri.parse("IAP protected URL.........."),
body: null, //null FOR TESTING
headers: {
"Authorization": "Bearer " + googleSignInAuthentication.idToken
}
);
However, if I try the same code after JWT has expired, response.body is:
OpenID Connect token expired: JWT has expired
I have checked for a solution and it seems I need a refreshToken
to get a new JWT, but as you can see in the User details from above, I am getting an empty string for the refreshToken
. I am not able to figure out what do I need to do so that I can get a refreshToken
in the original signIn() that can be used for requesting a new JWT
UPDATE 2021.05.29
Based on these two answers: Answer 1 & Answer 2 I tried the following code:
final UserCredential userCredential = await _auth.signInWithCredential(GoogleAuthProvider.credential(
accessToken: googleSignInAuthentication.accessToken,
idToken: null, // googleSignInAuthentication.idToken
));
[using idToken:googleSignInAuthentication.idToken
instead of idToken: null
above returned error: The supplied auth credential is malformed or has expired
]
which returned a new value for googleSignInAuthentication.accessToken
that I used in the below code as refresh_token
:
final url = Uri.parse('https://securetoken.googleapis.com/v1/token?key=$WEB_API_KEY');
final response = await http.post(
url,
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
body: {
'grant_type': 'refresh_token',
'refresh_token': googleSignInAuthentication.accessToken,
},
);
which returns INVALID_REFRESH_TOKEN
error.
If anyone who has faced similir issue in the past and has resolved it could shed some light on this, that will be a great help!!