web-dev-qa-db-fra.com

Comment autoriser une application (web ou installée) sans intervention de l'utilisateur?

Supposons que j'ai une application Web qui doit accéder aux fichiers Drive dans un service en arrière-plan. Il sera soit propriétaire des fichiers auxquels il accède, soit exécuté dans un compte Google avec lequel le propriétaire a partagé les documents.

Je comprends que mon application a besoin d'un jeton de rafraîchissement, mais je ne veux pas écrire le code pour l'obtenir car je ne le ferai qu'une seule fois.

NB: ceci n'utilise PAS de compte de service. L'application sera exécutée sous un compte Google classique. Le compte de service est une approche valable dans certaines situations. Cependant, la technique d'utilisation de Oauth Playground pour simuler l'application peut économiser un tas d'efforts redondants et s'applique à toutes les API pour lesquelles le partage avec un compte de service n'est pas pris en charge.

59
pinoyyid

Cela peut être fait avec le terrain de jeu Oauth2 à https://developers.google.com/oauthplayground

Pas:-

  1. Créez le compte Google (par exemple, [email protected]) - Ou ignorez cette étape si vous utilisez un compte existant.
  2. Utilisez la console API pour enregistrer mydriveapp ( https://console.developers.google.com/apis/credentials/oauthclient?project=mydriveapp ou simplement https: //console.developers .google.com/apis / )
  3. Créez un nouvel ensemble d'informations d'identification. Credentials/Create Credentials/OAuth Client Id puis sélectionnez Web application
  4. Inclure https://developers.google.com/oauthplayground comme URI de redirection valide
  5. Notez l'ID client (application Web) et le secret client
  6. Connectez-vous en tant que [email protected]
  7. Aller à l'aire de jeux Oauth2
  8. Dans Paramètres (icône d'engrenage), définissez
    • Flux Oauth: serveur
    • Type d'accès: hors ligne
    • Utilisez vos propres informations d'identification OAuth: TICK
    • Identifiant client et secret client: à partir de l'étape 5
  9. Cliquez sur Étape 1 et choisissez Drive API https://www.googleapis.com/auth/drive (cela dit, cette technique fonctionne également pour toutes les API Google répertoriées)
  10. Cliquez sur Autoriser les API. Vous serez invité à choisir votre compte Google et à confirmer l'accès
  11. Cliquez sur Étape 2 et "Code d'autorisation d'échange pour les jetons"
  12. Copiez le jeton d'actualisation renvoyé et collez-le dans votre application, le code source ou dans une forme de stockage à partir de laquelle votre application peut le récupérer.

Votre application peut désormais fonctionner sans surveillance et utiliser le jeton d'actualisation comme décrit https://developers.google.com/accounts/docs/OAuth2WebServer#offline pour obtenir un jeton d'accès.

NB. Sachez que le jeton d'actualisation peut être expiré par Google, ce qui signifie que vous devez répéter les étapes 5 pour obtenir un nouveau jeton d'actualisation. Le symptôme de ceci sera une subvention non valide retournée lorsque vous essayez d'utiliser le jeton d'actualisation.

NB2. Cette technique fonctionne bien si vous voulez une application Web qui accède à votre propre (et uniquement votre propre) compte Drive, sans prendre la peine d'écrire le code d'autorisation qui ne doit être exécuté qu'une seule fois. Ignorez simplement l'étape 1 et remplacez "my.drive.app" par votre propre adresse e-mail à l'étape 6. assurez-vous que vous êtes conscient des implications de sécurité si le jeton d'actualisation est volé.

Voir le commentaire de Woody ci-dessous où il renvoie à cette vidéo Google https://www.youtube.com/watch?v=hfWe1gPCnzc

. . .

Voici une routine JavaScript rapide qui montre comment utiliser le jeton d'actualisation à partir du OAuth Playground pour répertorier certains fichiers Drive. Vous pouvez simplement le copier-coller dans Chrome = dev console, ou exécutez-le avec node. Bien sûr, fournissez vos propres informations d'identification (celles ci-dessous sont toutes fausses).

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();
117
pinoyyid

Permettez-moi d'ajouter un itinéraire alternatif à l'excellente réponse de pinoyyid (qui n'a pas fonctionné pour moi - des erreurs de redirection popping).

Au lieu d'utiliser OAuthPlayground, vous pouvez également utiliser l'API HTTP REST directement. La différence par rapport à la réponse de pinoyyid est que nous ferons les choses localement. Suivez les étapes 1 à 3 de la réponse de pinoyyid. I ' Je vais les citer:

  1. Créez le compte Google (par exemple, [email protected]) - Ou ignorez cette étape si vous utilisez un compte existant.
  2. Utilisez la console API pour enregistrer mydriveapp ( https://console.developers.google.com/apis/credentials/oauthclient?project=mydriveapp ou simplement https: //console.developers .google.com/apis / )
  3. Créez un nouvel ensemble d'informations d'identification (NB OAuth ID client et non clé de compte de service, puis choisissez "Application Web" dans la sélection)

Maintenant, au lieu du terrain de jeu, ajoutez ce qui suit à vos informations d'identification:

Sources JavaScript autorisées: http: // localhost (Je ne sais pas si cela est requis mais faites-le.)
URI de redirection autorisés: http: // localhost: 808

Capture d'écran (en allemand):

OAuth source/redirect settings

Assurez-vous que enregistrez réellement vos modifications via le bouton bleu ci-dessous!

Maintenant, vous voudrez probablement utiliser une interface graphique pour créer vos requêtes HTTP. J'ai utilisé Insomnia mais vous pouvez aller avec Postman ou cURL simple. Je recommande Insomnia car il vous permet de parcourir facilement les écrans de consentement.

Créez une nouvelle requête [~ # ~] obtenez [~ # ~] avec les paramètres suivants:

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

Si votre outil de choix ne gère pas l'encodage URL automatiquement, assurez-vous de bien le faire vous-même.

Avant de lancer votre demande, configurez un serveur Web pour écouter sur http://localhost:8080. Si vous avez installé node et npm, exécutez npm i express, puis créez un 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!');
});

Et exécutez le serveur via node index.js. Je vous conseille de ne pas enregistrer l'intégralité de l'objet req ou d'exécuter node index.js | less pour la sortie complète sera énorme.
Il existe également des solutions très simples pour d'autres langues. Par exemple. utiliser le serveur Web intégré de PHP sur 8080 php -S localhost:8080.

Maintenant, lancez votre demande (dans Insomnia) et vous devriez être invité avec la connexion:

login Prompt

Connectez-vous avec votre e-mail et votre mot de passe et confirmez l'écran de consentement (devrait contenir les portées que vous avez choisies).

Retournez à votre terminal et vérifiez la sortie. Si vous avez enregistré le tout, faites défiler vers le bas (par exemple, pgdown en moins) jusqu'à ce que vous voyiez une ligne avec code=4/....

Copiez ce code; c'est votre code d'autorisation que vous voudrez échanger contre un jeton d'accès et d'actualisation. Ne copiez pas trop - s'il y a une esperluette & ne le copiez pas ou quoi que ce soit après. & délimite les paramètres de requête. Nous voulons juste le code.

Configurez maintenant une requête HTTP POST pointant vers https://www.googleapis.com/oauth2/v4/token as URL du formulaire encodée. Dans Insomnia, vous pouvez simplement cliquer dessus - dans d'autres outils, vous devrez peut-être définir vous-même l'en-tête sur Content-Type: application/x-www-form-urlencoded.

Ajoutez les paramètres suivants:

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

Encore une fois, assurez-vous que l'encodage est correct.

Déclenchez votre demande et vérifiez la sortie de votre serveur. Dans la réponse, vous devriez voir un objet JSON:

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

Vous pouvez utiliser le access_token tout de suite mais il ne sera valable qu'une heure. Notez le jeton d'actualisation. C'est celui que vous pouvez toujours * échanger contre un nouveau jeton d'accès.

* Vous devrez répéter la procédure si l'utilisateur change son mot de passe, révoque l'accès, est inactif pendant 6 mois, etc.

Heureux OAuthing!

2
m02ph3u5