Generating a refresh token for YouTube API calls using the OAuth playground

By: Google Developers

110   9   43067

Uploaded on 07/26/2013

This tutorial demonstrates the steps it takes to generate a long-lived refresh token for your client ID/client secret pair using the OAuth 2.0 playground. This technique is useful for testing or for uncommon scenarios where you may need to generate a long-lived refresh token without having to include the 3-legged OAuth flow into your own applications.

Comments (5):

By anonymous    2017-09-20

This can be done with the Oauth2 Playground at https://developers.google.com/oauthplayground

Steps:-

  1. Create the Google Account (eg. my.drive.app@gmail.com)
  2. Use the API console to register the mydriveapp (https://console.developers.google.com/apis/credentials/oauthclient?project=mydriveapp or just https://console.developers.google.com/apis/)
  3. Create a new set of credentials (NB OAuth Client ID not Service Account Key and then choose "Web Application" from the selection)
  4. Include https://developers.google.com/oauthplayground as a valid redirect URI
  5. Note the client ID (web app) and Client Secret
  6. Login as my.drive.app@gmail.com
  7. Go to Oauth2 playground
  8. In Settings (gear icon), set
    • Oauth flow: server
    • Access type: offline
    • Use your own OAuth credentials: TICK
    • Client Id and Client Secret: from step 5
  9. Click Step 1 and choose Drive API https://www.googleapis.com/auth/drive (having said that, this technique also works for any of the Google APIs listed)
  10. Click Authorize APIs. You will be prompted to choose your Google account and confirm access
  11. Click Step 2 and "Exchange Authorization code for tokens"
  12. Copy the returned Refresh Token and paste it into your app, source code or in to some form of storage from where your app can retrieve it.

Your app can now run unattended, and use the Refresh Token as described https://developers.google.com/accounts/docs/OAuth2WebServer#offline to obtain an Access Token.

NB. Be aware that the refresh token can be expired by Google which will mean that you need to repeat steps 5 onwards to get a new refresh token. The symptom of this will be a Invalid Grant returned when you try to use the refresh token.

NB2. This technique works well if you want a web app which access your own (and only your own) Drive account, without bothering to write the authorization code which would only ever be run once. Just skip step 1, and replace "my.drive.app" with your own email address in step 5. make sure you are aware of the security implications if the Refresh Token gets stolen.

See Woody's comment below where he links to this Google video https://www.youtube.com/watch?v=hfWe1gPCnzc

. . .

Here is a quick JavaScript routine that shows how to use the Refresh Token from the OAuth Playground to list some Drive files. You can simply copy-paste it into Chrome dev console, or run it with node. Of course provide your own credentials (the ones below are all fake).

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

Original Thread

By anonymous    2017-09-20

Looking at the screenshots, you have created a Service Account. Service Accounts use two-legged OAuth, and therefore do not have any user-consent-and-redirect dance.

A Service Account would not have permissions to videos in your personal Gmail account. Maybe that's OK, maybe it isn't. It depends on your use case which you don't describe in your question. If you need your application to act with the same permissions as your Gmail account, you'll need to use a slightly different technique. (described How do I authorise an app (web or installed) without user intervention? (canonical ?) and https://www.youtube.com/watch?v=hfWe1gPCnzc)

Original Thread

By anonymous    2017-10-30

I use NodeJS, I want to insert in my script a function to insert a video to a specific playlist.

I saw a lot on internet, and I know Youtube api requires OAuth to work, and so, some HTML page / callback to get the Token.

Did I miss something or is it impossible to handle this token in script without any user interaction ?

Is there a simple example of how doing this ? I tried this using youtube-api npm :

var express = require('express');
var router = express.Router(),
   Youtube = require("youtube-api"),
   fs = require('fs'),

router.get('/insert', function(req, res, next) {
    Youtube.authenticate({
        type: "oauth"
      , token: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxZ9F0sVpqEXh"
    });

    var req = Youtube.videos.insert({
        "resource": {
            // Video title and description
            "snippet": {
                "title": "Test",
                "description": "Test video upload via YouTube API"
            },
            "status": {
                "privacyStatus": "private"
            }
        }, 
        "part": "snippet,status,id", 
        "media": {
            "body": fs.createReadStream('./test.mp4')
        }
    }, function (err, data) {
        console.log(err);

        // insert to playlist
        Youtube.playlistItems.insert({
            "resource": {
                "snippet": {
                    "playlistId": "xxxxxxxxxxxxxxxxxxxgvjIu",
                    "resourceId": {
                      "kind": "youtube#video",
                      "videoId": data.id // ???
                    }
                },
                "status": {
                    "privacyStatus": "private"
                }
            }

        }, function (err, data) {
            if (err) {
                return console.log(err); 
            }
        });         
    });

    res.json();
});

I got error 401 :

message: 'Login Required'

EDIT 1

Good video to start : https://www.youtube.com/watch?v=hfWe1gPCnzc

I got a token now, but don't know how to get no limit no this... Now I changed :

Youtube.authenticate({
    type: "oauth"
  , token: "token_from_google"
});

And I got the error :

message: 'The request cannot be completed because you have exceeded your quota.' } ],
code: 403, message: 'The request cannot be completed because you have exceeded your quota.

I can't understand it ... ?

Original Thread

Popular Videos 3001

Submit Your Video

If you have some great dev videos to share, please fill out this form.