I am trying to use the New Google Sign-In API for authenticating with my own backend server. Every call to my server contains the idToken jwt as a Bearer token. On the backend side, I validate the token by checking the signature, and checking if the token is expired or not. The problem is that the New Google Sign-In API returns jwts with 1 hour expiration time, but I could not find any way to refresh the token.
How I get the idToken client side
fun showSignInDialog() {
val request = GetSignInIntentRequest.builder()
.setServerClientId(GOOGLE_SERVER_CLIENT_ID)
.build()
Identity.getSignInClient(context)
.getSignInIntent(request)
.addOnSuccessListener {
googleSignInLauncher.launch(IntentSenderRequest.Builder(it).build())
}
}
fun handleSignInResult(result: ActivityResult) {
val credential = Identity.getSignInClient(context)
.getSignInCredentialFromIntent(result.data)
// later this token will be used for querying user-related data on my backend
setToken(credential.googleIdToken)
}
How I validate my endpoints on the backend side
fun Application.installAuthentication() {
val googleJwtIssuer = environment.config.property("jwt.google.domain").getString()
val googleJwtAudience = environment.config.property("jwt.google.audience").getString()
val jwtRealm = environment.config.property("jwt.google.realm").getString()
val googleJwkProvider = JwkProviderBuilder(URL("https://www.googleapis.com/oauth2/v3/certs"))
.cached(10, 24, TimeUnit.HOURS)
.rateLimited(10, 1, TimeUnit.MINUTES)
.build()
install(Authentication) {
jwt("google") {
verifier(googleJwkProvider) {
withIssuer(googleJwtIssuer)
withAudience(googleJwtAudience)
}
realm = jwtRealm
validate { credentials ->
if (credentials.payload.audience.contains(googleJwtAudience))
JWTPrincipal(credentials.payload)
else
null
}
}
}
}
// in my main
installAuthentication()
routing {
authenticate("google") {
get("/get-todos") {
val payload = call.principal<JWTPrincipal>()?.payload ?: error("JWTPrincipal not found")
call.respond(getTodos(payload.subject))
}
}
}
Sample JWT returned by the google sign in API (on first sign in)
{
"iss": "https://accounts.google.com",
"azp": "secret",
"aud": "secret",
"sub": "secret",
"email": "[email protected]",
"email_verified": true,
"name": "Ben Jerry",
"picture": "https://lh3.googleusercontent.com/secret",
"given_name": "Patrik",
"family_name": "Aradi",
"locale": "en-GB",
"iat": 1616243551,
"exp": 1616247151
}
It does not have a refresh token in it unfortunatelly
I ended up using the old GoogleSignInApi's silent sign in feature for this. I've tested and if I use the New Google Sign In api for the sign in, the old one will still be able to perform the silent sign in.
It would be nice, if the new one had this silent sign in feature, but for now it looks like if you would like this "refresh" feature, you're still required to use the old api.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With