Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migrating from YouTube ClientLogin to OAuth 2.0

I have an app that uploads Video to YouTube to a specific YouTube channel (meaning, not to any individual user's channel, but to a single channel, for which I have the Username and Password).

In the ClientLogin my server-side process provided YouTube with the U/P and everything moved ahead. However, that's being deprecated and I'm looking to upgrade to OAuth 2.0 (as per their recommendation), however, the documentation insists on there being a redirect URI, for when the user has logged in. It doesn't seem to explain how to bypass the user login (since the user has nothing to log into, or any credentials to log in *with... the app is designed to take their video and upload it to OUR channel). So, what I need is to bypass the user being asked anything, and for YouTube to simply take my channel credentials and give me back the token for me to do the upload with.

I realize that this is a totally standard and non-controversial procedure, so I *MUST be missing something obvious, but I just can't suss out what that is.

So, my question is, how do I skip the user dialog-> redirect and just provide youtube with credentials for it to accept and then upload my video in OAuth 2.0?

What I'm really after is to do follow the DirectUpload approach here: https://developers.google.com/youtube/2.0/developers_guide_protocol#AuthSub_Authentication_Flow And to have retrieved the user Token silently behind the scenes.

TIA

like image 509
Yevgeny Simkin Avatar asked May 08 '12 00:05

Yevgeny Simkin


1 Answers

There really is no way (that I've found) to completely bypass visiting an external page to authorize the OAuth2.0 access. The closest I have come is to create an "Installed Application" project on code.google.com/apis/console and use the device methodology. You will receive a Client ID and Client Secret. These will be used later. Ideally you would generate a developer key, though I don't believe this to be required at this time, through code.google.com/apis/youtube/dashboard/

I use JSON notation for headers and responses, it should be easy to adapt to your language of choice.

First make a POST request to accounts.google.com/o/oauth2/device/code with the headers

{
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': post_data.length,
    'X-GData-Key': 'key=YOUR_DEVELOPER_KEY'
}

and the data containing:

{
client_id: 'YOUR_CLIENT_ID',
scope: 'https://gdata.youtube.com'
}

where YOUR_CLIENT_ID is the client ID you obtained for the google apis project you set up earlier.

You will get a response like this:

{
  "device_code" : "4/Pj8m71w5XuEMTT0ZwOJVgvlTfF4Q",
  "user_code" : "5wtw67wm",
  "verification_url" : "http://www.google.com/device",
  "expires_in" : 1800,
  "interval" : 5
}

If you don't visit www.google.com/device (defined by the "verification_url" field) within 30 minutes (1800 seconds per the "expires_in" response field), you will have to perform this first request again. On the www.google.com/device page, you will be asked to login if you aren't already and then enter the verification code (defined by the "user_code" response field). You will be presented with a request to authorize the application and a list of permissions the app is requesting. You want to store (at least temporarily) the value for the "device_code" field. This will be used when requesting an access token and refresh token.

Now that the permission has been granted, we can request an access/refresh token pair. This only needs to happen once provided you store the refresh token. To request the access/refresh token pair you must make a POST request to accounts.google.com/o/oauth2/token with the headers

{
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': post_data.length,
    'X-GData-Key': 'key=YOUR_DEVELOPER_KEY'
}

and the data

{
    client_id: 'YOUR_CLIENT_ID',
    client_secret: 'YOUR_CLIENT_SECRET',
    code: 'YOUR_DEVICE_CODE',
    grant_type: 'http://oauth.net/grant_type/device/1.0'
}

The response will look like this

{
  "access_token" : "YOUR_ACCESS_TOKEN",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "refresh_token" : "YOUR_REFRESH_TOKEN"
}

This specifies that the access token expires in 3600 seconds (60 minutes) and what your current access token is and what the refresh token is. You want to store the access token for use with your current session and the refresh token for future sessions.

When making an API request, you will want to include the access token in the Authorization header field as well as including the developer key as we have been all along. For uploading a video, I used these headers:

{
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'X-GData-Key': 'key=YOUR_DEVELOPER_KEY',
    'Slug': 'video.mp4',
    'Content-Type': 'multipart/related; boundary="f897a6d"',
    'Content-Length': post_length,
    'Connection': 'close'
}

You can refresh your access token at any time, not just when the old one expires. To refresh your access token, you make a POST request to accounts.google.com/o/oauth2/token with the headers

{
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': post_data.length,
    'X-GData-Key': 'key=YOUR_DEVELOPER_KEY'
}

and the data

{
    client_id: 'YOUR_CLIENT_ID',
    client_secret: 'YOUR_CLIENT_SECRET',
    refresh_token: 'YOUR_REFRESH_TOKEN',
    grant_type: 'refresh_token'
}

You will get a response like this

{
  "access_token" : "YOUR_NEW_ACCESS_TOKEN",
  "token_type" : "Bearer",
  "expires_in" : 3600
}

where YOUR_NEW_ACCESS_TOKEN is the new token for you to use in your future requests.

like image 183
SnowInferno Avatar answered Nov 13 '22 15:11

SnowInferno