Wie autorisiere ich eine App (Web oder installiert) ohne Benutzereingriff?

73

Angenommen, ich habe eine Web-App, die in einem Hintergrunddienst auf Laufwerksdateien zugreifen muss. Es besitzt entweder die Dateien, auf die es zugreift, oder wird in einem Google-Konto ausgeführt, für das der Eigentümer die Dokumente freigegeben hat.

Ich verstehe, dass meine App ein Aktualisierungstoken benötigt, aber ich möchte den Code nicht schreiben, um das zu erhalten, da ich es immer nur einmal tun werde.

NB. Dies verwendet KEIN Dienstkonto. Die App wird unter einem herkömmlichen Google-Konto ausgeführt. Das Dienstkonto ist in einigen Situationen ein gültiger Ansatz. Die Technik der Verwendung von Oauth Playground zur Simulation der App kann jedoch eine Menge redundanten Aufwands einsparen und gilt für alle APIs, für die die Freigabe für ein Dienstkonto nicht unterstützt wird.

Pinoyyid
quelle

Antworten:

147

Dies kann mit dem Oauth2-Spielplatz unter https://developers.google.com/oauthplayground erfolgen

Schritte:-

  1. Erstellen Sie das Google-Konto (z. B. [email protected]) - oder überspringen Sie diesen Schritt, wenn Sie ein vorhandenes Konto verwenden.
  2. Verwenden Sie die API-Konsole, um die mydriveapp zu registrieren ( https://console.developers.google.com/apis/credentials/oauthclient?project=mydriveapp oder einfach https://console.developers.google.com/apis/ ).
  3. Erstellen Sie einen neuen Satz von Anmeldeinformationen. Credentials/Create Credentials/OAuth Client Iddann wählen SieWeb application
  4. Fügen Sie https://developers.google.com/oauthplayground als gültigen Umleitungs-URI hinzu
  5. Notieren Sie die Client-ID (Web-App) und das Client-Geheimnis
  6. Melden Sie sich als [email protected] an
  7. Gehe zum Oauth2-Spielplatz
  8. Stellen Sie unter Einstellungen (Zahnradsymbol) ein
    • OAuth-Fluss: Serverseitig
    • Zugriffsart: Offline
    • Verwenden Sie Ihre eigenen OAuth-Anmeldeinformationen: TICK
    • Kunden-ID und Kundengeheimnis: ab Schritt 5
  9. Klicken Sie auf Schritt 1 und wählen Sie Drive API v3 https://www.googleapis.com/auth/drive (diese Technik funktioniert jedoch auch für alle aufgeführten Google-APIs).
  10. Klicken Sie auf APIs autorisieren. Sie werden aufgefordert, Ihr Google-Konto auszuwählen und den Zugriff zu bestätigen
  11. Klicken Sie auf Schritt 2 und "Exchange-Autorisierungscode für Token".
  12. Kopieren Sie das zurückgegebene Aktualisierungstoken und fügen Sie es in Ihre App, Ihren Quellcode oder in einen Speicher ein, von dem Ihre App es abrufen kann.

Ihre App kann jetzt unbeaufsichtigt ausgeführt werden und das Aktualisierungstoken wie beschrieben unter https://developers.google.com/accounts/docs/OAuth2WebServer#offline verwenden , um ein Zugriffstoken zu erhalten.

NB. Beachten Sie, dass das Aktualisierungstoken von Google abgelaufen sein kann. Dies bedeutet, dass Sie die Schritte ab 5 wiederholen müssen, um ein neues Aktualisierungstoken zu erhalten. Das Symptom hierfür ist eine ungültige Gewährung, die zurückgegeben wird, wenn Sie versuchen, das Aktualisierungstoken zu verwenden.

NB2. Diese Technik funktioniert gut, wenn Sie eine Web-App möchten, die auf Ihr eigenes (und nur Ihr eigenes) Drive-Konto zugreift, ohne den Autorisierungscode schreiben zu müssen, der nur einmal ausgeführt wird. Überspringen Sie einfach Schritt 1 und ersetzen Sie "my.drive.app" in Schritt 6 durch Ihre eigene E-Mail-Adresse. Stellen Sie sicher, dass Sie sich der Auswirkungen auf die Sicherheit bewusst sind, wenn das Aktualisierungstoken gestohlen wird.

Siehe Woodys Kommentar unten, wo er auf dieses Google-Video https://www.youtube.com/watch?v=hfWe1gPCnzc verlinkt

. . .

Hier ist eine kurze JavaScript-Routine, die zeigt, wie Sie mit dem Aktualisierungstoken vom OAuth-Spielplatz einige Laufwerksdateien auflisten. Sie können es einfach kopieren und in die Chrome Dev Console einfügen oder mit Node ausführen. Geben Sie natürlich Ihre eigenen Anmeldeinformationen an (die folgenden sind alle gefälscht).

function get_access_token_using_saved_refresh_token() {
    // from the oauth playground
    const refresh_token = "1/0PvMAoF9GaJFqbNsLZQg-f9NXEljQclmRP4Gwfdo_0";
    // from the API console
    const client_id = "559798723558-amtjh114mvtpiqis80lkl3kdo4gfm5k.apps.googleusercontent.com";
    // from the API console
    const client_secret = "WnGC6KJ91H40mg6H9r1eF9L";
    // from https://developers.google.com/identity/protocols/OAuth2WebServer#offline
    const refresh_url = "https://www.googleapis.com/oauth2/v4/token";

    const post_body = `grant_type=refresh_token&client_id=${encodeURIComponent(client_id)}&client_secret=${encodeURIComponent(client_secret)}&refresh_token=${encodeURIComponent(refresh_token)}`;

    let refresh_request = {
        body: post_body,
        method: "POST",
        headers: new Headers({
            'Content-Type': 'application/x-www-form-urlencoded'
        })
    }

    // post to the refresh endpoint, parse the json response and use the access token to call files.list
    fetch(refresh_url, refresh_request).then( response => {
            return(response.json());
        }).then( response_json =>  {
            console.log(response_json);
            files_list(response_json.access_token);
    });
}

// a quick and dirty function to list some Drive files using the newly acquired access token
function files_list (access_token) {
    const drive_url = "https://www.googleapis.com/drive/v3/files";
    let drive_request = {
        method: "GET",
        headers: new Headers({
            Authorization: "Bearer "+access_token
        })
    }
    fetch(drive_url, drive_request).then( response => {
        return(response.json());
    }).then( list =>  {
        console.log("Found a file called "+list.files[0].name);
    });
}

get_access_token_using_saved_refresh_token();
Pinoyyid
quelle
6
Beachten Sie, dass meine Untersuchungen ergeben haben, dass Aktualisierungstoken "langlebig" sind und nicht von Google abgelaufen sind, sondern in der API-Konsole widerrufen werden können. Außerdem hat Google ein kurzes 4-minütiges Video darüber, wie Sie ein Aktualisierungstoken von Playground erhalten: youtube.com/watch?v=hfWe1gPCnzc
woody
2
In Wirklichkeit ist es viel sauberer, wenn Sie auch eine separate Setup-Seite codieren, die das Aktualisierungstoken generiert, indem Sie einem Administrator die Erlaubnis erteilen. Der Administrator verwendet die Seite, um die App bereitzustellen oder später neu zu konfigurieren. Die Verwendung des oauth-Spielplatzes ist nur ein schneller Weg, um das Schreiben einer solchen Administrationsseite zu vermeiden.
Zig Mandel
13
In Wirklichkeit ist es viel sauberer, wenn Sie überhaupt nichts codieren. Warum Stunden, wenn nicht Tage damit verschwenden, OAuth herauszufinden und die undichten Abstraktionen der Google-Bibliotheken zu streiten, alles für eine App, die Sie nur einmal ausführen werden? Das ist nicht sauber, es ist grenzwertig verrückt.
Pinoyyid
1
Wo führe ich Schritt 3 aus? Auch V2 wird nicht angezeigt. Ich werde es mit Drive V3 versuchen
Dan
6
Dies ist die beste Antwort aller Zeiten. Ich würde es zehn Stimmen geben, wenn ich könnte. Du hast gerade den oauth Wahnsinn erträglich gemacht. Vielen Dank!
mga
6

Lassen Sie mich einen alternativen Weg zu Pinoyyids hervorragender Antwort hinzufügen (was bei mir nicht funktioniert hat - knallende Umleitungsfehler).

Anstelle von OAuthPlayground können Sie auch die HTTP-REST-API direkt verwenden. Der Unterschied zu Pinoyyids Antwort besteht also darin, dass wir die Dinge vor Ort erledigen. Befolgen Sie die Schritte 1 bis 3 aus Pinoyyids Antwort. Ich werde sie zitieren:

  1. Erstellen Sie das Google-Konto (z. B. [email protected]) - oder überspringen Sie diesen Schritt, wenn Sie ein vorhandenes Konto verwenden.
  2. Verwenden Sie die API-Konsole, um die mydriveapp zu registrieren ( https://console.developers.google.com/apis/credentials/oauthclient?project=mydriveapp oder einfach https://console.developers.google.com/apis/ ).
  3. Erstellen Sie einen neuen Satz von Anmeldeinformationen (NB OAuth-Client-ID, nicht Dienstkontoschlüssel, und wählen Sie dann "Webanwendung" aus der Auswahl aus).

Fügen Sie jetzt anstelle des Spielplatzes Folgendes zu Ihren Anmeldeinformationen hinzu:

Autorisierte JavaScript-Quellen: http: // localhost (Ich weiß nicht, ob dies erforderlich ist, aber mache es einfach.)
Autorisierte Umleitungs-URIs: http: // localhost: 8080

Screenshot:

OAuth-Quell- / Umleitungseinstellungen

Stellen Sie sicher, dass Sie Ihre Änderungen tatsächlich über die blaue Schaltfläche unten speichern !

Jetzt möchten Sie wahrscheinlich eine GUI verwenden, um Ihre HTTP-Anforderungen zu erstellen. Ich habe Schlaflosigkeit benutzt, aber du kannst mit Postman gehen oder CURL gehen. Ich empfehle Insomnia, da Sie damit problemlos die Einwilligungsbildschirme durchgehen können.

Erstellen Sie eine neue GET- Anforderung mit den folgenden Parametern:

URL: https://accounts.google.com/o/oauth2/v2/auth
Query Param: redirect_uri=http://localhost:8080
Query Param: prompt=consent
Query Param: response_type=code
Query Param: client_id=<your client id from OAuth credentials>
Query Param: scope=<your chosen scopes, e.g. https://www.googleapis.com/auth/drive.file>
Query Param: access_type=offline

Wenn das Tool Ihrer Wahl die URL-Codierung nicht automatisch verarbeitet, stellen Sie sicher, dass Sie es selbst richtig machen.

Richten Sie vor dem Auslösen Ihrer Anfrage einen Webserver zum Abhören ein http://localhost:8080. Wenn Sie Node und Npm installiert haben npm i express, erstellen Sie Folgendes index.js:

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('ok');
  console.log(req)
});

app.listen(8080, function () {
  console.log('Listening on port 8080!');
});

Und führen Sie den Server über node index.js. Ich empfehle, entweder nicht das gesamte reqObjekt zu protokollieren oder node index.js | lessdie vollständige Ausgabe auszuführen, da dies sehr umfangreich ist.
Auch für andere Sprachen gibt es sehr einfache Lösungen. Verwenden Sie beispielsweise PHPs integrierten Webserver auf 8080 php -S localhost:8080.

Feuern Sie nun Ihre Anfrage ab (in Insomnia) und Sie sollten mit dem Login aufgefordert werden:

Anmeldeaufforderung

Melden Sie sich mit Ihrer E-Mail-Adresse und Ihrem Passwort an und bestätigen Sie den Zustimmungsbildschirm (sollte die von Ihnen gewählten Bereiche enthalten).

Gehen Sie zurück zu Ihrem Terminal und überprüfen Sie die Ausgabe. Wenn Sie das Ganze protokolliert haben, scrollen Sie nach unten (z. B. pgdown in weniger), bis Sie eine Zeile mit sehen code=4/....

Kopieren Sie diesen Code. Es ist Ihr Autorisierungscode, den Sie gegen ein Zugriffs- und Aktualisierungstoken eintauschen möchten. Kopieren Sie nicht zu viel - wenn es ein kaufmännisches Und &gibt, kopieren Sie es nicht oder irgendetwas danach. &begrenzt Abfrageparameter. Wir wollen nur das code.

Richten Sie nun eine HTTP-POST-Anforderung ein, die auf eine https://www.googleapis.com/oauth2/v4/tokenals Formular-URL codierte URL verweist . In Insomnia können Sie einfach darauf klicken - in anderen Tools müssen Sie den Header möglicherweise selbst festlegen Content-Type: application/x-www-form-urlencoded.

Fügen Sie die folgenden Parameter hinzu:

code=<the authorization code from the last step>
client_id=<your client ID again>
client_secret=<your client secret from the OAuth credentials>
redirect_uri=http://localhost:8080
grant_type=authorization_code

Stellen Sie erneut sicher, dass die Codierung korrekt ist.

Feuern Sie Ihre Anfrage ab und überprüfen Sie die Ausgabe von Ihrem Server. In der Antwort sollte ein JSON-Objekt angezeigt werden:

{
  "access_token": "xxxx",
  "expires_in": 3600,
  "refresh_token": "1/xxxx",
  "scope": "https://www.googleapis.com/auth/drive.file",
  "token_type": "Bearer"
}

Sie können das access_tokensofort verwenden, es ist jedoch nur eine Stunde gültig. Beachten Sie das Aktualisierungstoken. Dies ist diejenige, die Sie jederzeit * gegen ein neues Zugriffstoken eintauschen können.

* Sie müssen den Vorgang wiederholen, wenn der Benutzer sein Passwort ändert, den Zugriff widerruft, 6 Monate lang inaktiv ist usw.

Glückliche OAuthing !

m02ph3u5
quelle
Ich habe gerade meine Anweisungen überprüft und sie funktionieren einwandfrei. Wenn Sie ein Problem haben, bedeutet dies, dass Sie einen Fehler bei 3,4 oder 8 gemacht haben.
Pinoyyid
Wahrscheinlich, aber ich konnte den Fehler nicht erkennen. Ein Pfad ohne Spielplatz kann nützlich sein, wenn der Spielplatz nicht erreichbar ist.
m02ph3u5