1
votes

I have an application that can upload video in my youtube account, but after upgrading to YouTube API v3, the situation is complicated.

it used this implementation https://developers.google.com/youtube/2.0/developers_guide_protocol_browser_based_uploading

Youtube authorization previously looked like this.

$postData = "Email=".urlencode(Config::$youtubeEmail)."&Passwd=".urlencode(Config::$youtubePassword)."&service=youtube&source=".urlencode(Config::$youtubeAppName);
    $curl = curl_init("https://www.google.com/youtube/accounts/ClientLogin");
    curl_setopt($curl,CURLOPT_HEADER,"Content-Type:application/x-www-form-urlencoded");
    curl_setopt($curl,CURLOPT_POST,1);
    curl_setopt($curl,CURLOPT_POSTFIELDS,$postData);
    curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,0);
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
    curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,1);
    $response = curl_exec($curl);
    curl_close($curl);
    //print_r($response);exit();
    list($this->auth,$this->youtubeUser) = explode("\n",$response);
    list($this->authLabel,$this->authValue) = array_map("trim",explode("=",$this->auth));
    list($this->youtubeUserlabel,$this->youtubeUserValue) = array_map("trim",explode("=",$this->youtubeUser));

I received auth token, that was used to make auth token to youtube account, and was possible to upload video via form

$youtubeVideoKeywords = ""; // This is the uploading video keywords.
    $youtubeVideoCategory = $this->getVideoCategory(); // This is the uploading video category. There are only certain categories that are accepted. See below the method
    $data = '<?xml version="1.0"?'.'>
    <entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">
        <media:group>
            <media:title type="plain">'.stripslashes($youtubeVideoTitle).'</media:title>
            <media:description type="plain">'.stripslashes($youtubeVideDescription).'</media:description>
            <media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">'.$youtubeVideoCategory.'</media:category>
            <media:keywords>'.$youtubeVideoKeywords.'</media:keywords>
        </media:group>
        <yt:accessControl action="list" permission="denied"/>
    </entry>';
    $headers = array(
        'Authorization: Bearer ' . $this->authValue,
        'GData-Version: 2',
        'X-GData-Key: key=' . Config::$youtubeDevKey,
        'Content-Type: application/atom+xml; charset=UTF-8'
    );

    $curl = curl_init("http://gdata.youtube.com/action/GetUploadToken");
    curl_setopt($curl,CURLOPT_USERAGENT,$_SERVER["HTTP_USER_AGENT"]);
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($curl,CURLOPT_TIMEOUT,10);
    curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($curl,CURLOPT_POST,1);
    curl_setopt($curl,CURLOPT_FOLLOWLOCATION,1);
    curl_setopt($curl,CURLOPT_HTTPHEADER,$headers);
    curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
    curl_setopt($curl,CURLOPT_REFERER,true);
    curl_setopt($curl,CURLOPT_HEADER,0);
    $response = simplexml_load_string(curl_exec($curl));
    curl_close($curl);
    return $response;

I didnt need any permission to upload video, user only used form where writed title, desc etc, pickedup video from computer and hit upload. Everything was fine, users could upload video to my youtube channel. useres ere satisfied, because there wasn´t additional login.

But now, when i make curl request to https://www.google.com/youtube/accounts/ClientLogin it says, that i need oauth2.0 auth service.

So i generated oauth2 secrets to my service, made changes to code, but when user want to use this application he need to be logged to google account and allow permissions to use web app.

New code snippet:

When user want to upload video, i check for auth code from oauth2service, and make curl for code, if doesnt exist

$url = 'https://accounts.google.com/o/oauth2/v2/auth?';
$url .= 'client_id='   . Config::$googleClientId;
$url .= '&redirect_uri=' . urlencode(Config::$googleRedirectUrl);
$url .= '&scope=' . urlencode("https://www.googleapis.com/auth/youtube");
$url .= '&response_type=code';

It returns me to redirect page, when i get a code, store it to application for later use. User write down info about video, and hit next button. I make new thread to upload service, use generated code to get a access token, which is used to form upload

$curl = curl_init('https://accounts.google.com/o/oauth2/token');

    $post_fields = array(
        'code'     => $code,
        'client_id'   => Config::$googleClientId,
        'client_secret' => Config::$googleSecretCode,
        'redirect_uri' => Config::$googleRedirectUrl,
        'grant_type'  => 'authorization_code'
    );
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post_fields));

    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/x-www-form-urlencoded'
    ));

    //send request
    $response = curl_exec($curl);
    curl_close($curl);

    $json = json_decode($response,true);

    $this->authValue = $json["access_token"];

    // The method returns response xml
    $response = false;
    $youtubeVideoKeywords = ""; // This is the uploading video keywords.
    $youtubeVideoCategory = $this->getVideoCategory(); // This is the uploading video category. There are only certain categories that are accepted. See below the method
    $data = '<?xml version="1.0"?'.'>
    <entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">
        <media:group>
            <media:title type="plain">'.stripslashes($youtubeVideoTitle).'</media:title>
            <media:description type="plain">'.stripslashes($youtubeVideDescription).'</media:description>
            <media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">'.$youtubeVideoCategory.'</media:category>
            <media:keywords>'.$youtubeVideoKeywords.'</media:keywords>
        </media:group>
        <yt:accessControl action="list" permission="denied"/>
    </entry>';
    $headers = array(
        'Authorization: Bearer ' . $this->authValue,
        'GData-Version: 2',
        'X-GData-Key: key=' . Config::$youtubeDevKey,
        'Content-Type: application/atom+xml; charset=UTF-8'
    );

    $curl = curl_init("http://gdata.youtube.com/action/GetUploadToken");
    curl_setopt($curl,CURLOPT_USERAGENT,$_SERVER["HTTP_USER_AGENT"]);
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($curl,CURLOPT_TIMEOUT,10);
    curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($curl,CURLOPT_POST,1);
    curl_setopt($curl,CURLOPT_FOLLOWLOCATION,1);
    curl_setopt($curl,CURLOPT_HTTPHEADER,$headers);
    curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
    curl_setopt($curl,CURLOPT_REFERER,true);
    curl_setopt($curl,CURLOPT_HEADER,0);
    $response = simplexml_load_string(curl_exec($curl));
    curl_close($curl);
    return $response;

Everything is fine, now i have got form, where action is to youtube server with token. everything work.

But now needs a user's consent to use web application, why? i have got my youtube account where videos are stored, no need information about user google account. Its very annoying, because user must be logged to application, after login it tells you, that must be logged to google account...

is there any workaround/solution that can make upload video to my youtube channel same easy as before without oauth2 please?

1

1 Answers

0
votes

You need to setup with a service account which means assigning domain-wide delegations: https://console.developers.google.com/apis/credentials

"To support server-to-server interactions, first create a service account for your project in the API Console. If you want to access user data for users in your G Suite domain, then delegate domain-wide access to the service account. Then, your application prepares to make authorized API calls by using the service account's credentials to request an access token from the OAuth 2.0 auth server. Finally, your application can use the access token to call Google APIs."

Help: https://developers.google.com/identity/protocols/OAuth2ServiceAccount

Without a service account it will always require a human user to accept a consent screen, whereas the service account bypasses the consent screen making it applicable for such operations where you wish for it to run in the background. It's not covered very well in their documentation (or I have yet to find a good resource... even though I feel like I've turned every stone on this planet).

I am having trouble getting tokens to work but have gotten service scripts working before... perhaps we can help one another? http://fb.com/jmt193 :)

I will reply to questions if you ask them.