Ich versuche, mithilfe von Google Apps Script einen Onlinedienst für meine Android-App zu erstellen. Die Benutzer melden sich einfach in der App bei ihrem Google-Konto an, erteilen dem entsprechenden GCP die erforderlichen Berechtigungen und dann kümmert sich die App darum, Zugriffstoken mit einem Aktualisierungstoken zu erhalten, um den Dienst im Namen des Benutzers aufzurufen. Das Hauptziel besteht darin, eine Tabelle auf dem Laufwerk des Benutzers zu ändern. Dies ist die Funktionalität, die ich erreichen möchte. Jetzt kommen die technischen Details.
Ich habe ein GCP- und ein Google Apps Script (GAS)-Projekt erstellt. In den Einstellungen des GASP legen Sie die ID des von mir erstellten GCP fest (anstelle der Standard-ID). Auf der GCP habe ich zwei Clients erstellt:
- Eine Android-App, die mein SHA-1 und meinen Paketnamen verwendet
- Ein Webclient zum Verwalten von OAuth-Tokens
In meiner Android-App verwende ich die Bibliothek com.google.android.gms:play-services-auth, um die Berechtigung des Benutzers mit den erforderlichen OAuth-Bereichen anzufordern (in diesem Beispiel). Fall:
https://www.googleapis.com/auth/spreadsheets). Die Bibliothek fordert das Dialogfeld ordnungsgemäß auf, meiner App die Berechtigung zu erteilen, und der Vorgang wird erfolgreich abgeschlossen. Von hier aus verwende ich einen benutzerdefinierten GASP (nicht mit dem vorherigen GCP verknüpft), um den Autorisierungscode gegen Aktualisierungs- und Zugriffstoken auszutauschen und neue Zugriffstoken vom Aktualisierungstoken zu erhalten. Die App kann diese Funktionen problemlos aufrufen und der Austausch mit den OAuth-Servern von Google erfolgt korrekt. Wenn ich zu meinem Google-Konto gehe (anders als das, das GCP und GASP enthält), kann ich die Verbindung zu meiner App sehen und die Berechtigungen werden korrekt angezeigt.
Jetzt möchte ich meine Funktion im GASP ausführen, das derzeit nur eine Tabelle auf dem Laufwerk des Benutzers erstellt und eine GET-Anfrage ausführt. So sieht die eigentliche Funktion aus:
Code: Select all
function doGet(e) {
let r = {}
try {
SpreadsheetApp.create("TEST")
r.status = "ok"
} catch (e) {
r.status = e.message
}
return ContentService.createTextOutput(JSON.stringify(r)).setMimeType(ContentService.MimeType.JSON)
}
Ich habe es als Web-App bereitgestellt, sodass es als der Benutzer ausgeführt wird, der darauf zugreift, und für jeden mit einem Google-Konto geöffnet ist.
Wenn ich einen Browser-Tab öffne, melde ich mich mit meinem autorisierten Google-Konto an und navigiere zu
https://script.google.com/macros/s/AKfy ... 518PhbpH6r[...]N1A/exec, dem Der Browser zeigt den JSON mit „status“: „ok“ an und die Tabelle wird auf meinem Laufwerk erstellt. Da keine Fehlermeldung angezeigt wird, gehe ich davon aus, dass der GASP über die erforderlichen Berechtigungen verfügt (bereits über meine Android-App erteilt). Dann wollte ich diese GET-Anfrage von meiner Android-App aus ausführen, oder grundsätzlich von jedem anderen Ort, der HTTP-Anfragen unterstützt. Sobald ich einen OkHttpClient mit einem Authenticator und einem Interceptor eingerichtet habe, die für die Authentifizierung sorgen, konnte ich die Funktion von meiner App aus nicht ausführen, ich erhalte immer einen 401-Fehler. Ich habe meine Anfrage innerhalb der Android-App in einem anderen GASP simuliert (nur eine Umgebung, die es mir ermöglicht, GET-Anfragen zu stellen):
Code: Select all
function request() {
let r = UrlFetchApp.fetch(
"https://script.google.com/macros/s/AKfycbx-sD70nS3Ee518PhbpH6ru_xWgCGr9Cj5pJBCjr[...]N1A/exec",
{
method: "get",
muteHttpExceptions: true,
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`
}
}
)
Logger.log(r.getResponseCode())
Logger.log(r.getContentText())
}
Und es überrascht nicht, dass ich die Fehlermeldung 401 erhalte und der Kontext ein HTML-Code von Google ist, der besagt, dass ich keinen Zugriff habe. Mein spezifisches Problem liegt also nicht im Android-Teil, sondern darin, wie ich mich authentifizieren kann, wenn ich die GET-Anfrage meines GASP aufrufe. Zur Klarstellung: Ich habe beim Testen ein neues Zugriffstoken erhalten, um sicherzustellen, dass es nicht abgelaufen ist. Ich habe im Internet gesucht und festgestellt, dass dies die angebliche Vorgehensweise ist, aber es funktioniert einfach nicht. Wir freuen uns über jede Hilfe!