Guilherme Delgado
04/26/2021, 4:38 PMconst val REDIRECT_LOCATION = "redirectLocation"
@KtorExperimentalLocationsAPI
@Location("/login/{provider?}/{redirectLocation?}")
class Login(val provider: String = "google", val redirectLocation: String = "")
@KtorExperimentalLocationsAPI
fun Route.login(client: HttpClient) {
authenticate(GOOGLE_OAUTH) {
get<Login> { params ->
val principal = call.authentication.principal<OAuthAccessTokenResponse>()
if (principal != null) {
val oauth = call.authentication.principal<OAuthAccessTokenResponse.OAuth2>()!!
val response = client.get<UserInfo>("<https://www.googleapis.com/oauth2/v1/userinfo>") {
header(HttpHeaders.Authorization, "Bearer ${oauth.accessToken}")
}
call.sessions.set(Session(response, oauth.accessToken, oauth.refreshToken ?: ""))
val to: Any = when(params.redirectLocation) {
AuthenticationRedirect.Reservations.toString() -> Reservations()
else -> Home()
}
call.redirect(to)
} else {
call.respond(status = HttpStatusCode.Unauthorized, "Unauthorized, no token issued")
}
}.param("error") {
handle {
call.respond(status = HttpStatusCode.Unauthorized, call.parameters.getAll("error").orEmpty().joinToString(", "))
}
}
}
}
Added this class since I could not pass Any as a parameter of @Location
sealed class AuthenticationRedirect {
object Home : AuthenticationRedirect() {
override fun toString(): String = "home"
}
object Reservations : AuthenticationRedirect() {
override fun toString(): String = "reservations"
}
}
Application.kt
urlProvider = { p -> redirectUrl(Login(p.name, request.call.parameters[REDIRECT_LOCATION] ?: ""), false) }
Finally, had to add the same redirect locations in my Project web client configurations in Cloud Console.
Don’t know if this is the best approach, but it’s working 🤔