Первое приложение для Flickr. Авторизация oAuth 2.0, получения списка фотографий

в 13:35, , рубрики: api, flickr, oauth 2.0, php, Веб-разработка, метки: ,

Документация по API на сайте flickr.com устарела. Уже давно появилась возможность авторизироваться через oAuth 2.0, но на сайте нет ни нормального описание, ни примеров работы с API после авторизации.

Авторизация на Flickr происходит в три этапа:

1. Получение oauth_token и oauth_token_secret. На первом шаге oauth_token это request_token.
2. Авторизация приложения в профиле пользователя.
3. Получения oauth_token и oauth_token_secret. На третьем шаге oauth_token это access_token.

Этап 1

Не знаю почему, но на этом этапе у меня пару раз из 10 выдает ошибку, поэтому я добавил рекурсию и если ошибка, то request_token зфпрашивается еще раз.

Все начинается по клику на кнопке

$("#flickr_connect").click(function(){
 flickrauth();
 return false;
});

function flickrauth(){
 $.ajax({
  type: "POST",
  url: "/auth/flickr.php?type=get_request_token",
  success: function(result){
   var oResult = $.parseJSON(result);
   if(oResult.oauth_problem == "signature_invalid"){
если вернулась ошибка, то вызываем еще раз
    flickrauth();
   }
   if(oResult.oauth_callback_confirmed == "true"){
если ошибки нет, то переходим к этапу два. Происходит редирект на flickr.com для авторизации нашего приложения
    oauth_token = oResult.oauth_token;
    location.href = "http://www.flickr.com/services/oauth/authorize?oauth_token="+oauth_token+"&perms=read";
   }
  }
 });
}

Ниже код, который вызывался в примере сверху

if($_GET["type"] == "get_request_token"){
 $request_token_url = "http://www.flickr.com/services/oauth/request_token";
 $oauth_nonce=md5(microtime().mt_rand());
 $timestamp = time();
 $consumer_key = "676d28f0d2ae990730a3fb232c252a8b";
 $consumer_secret = "36b056c53456fef";
 $sig_method = "HMAC-SHA1";
 $oauth_version = "1.0";
 $callback_url = "http://example.com/auth/flickr.php";

 $basestring = "oauth_callback=".urlencode($callback_url)."&oauth_consumer_key=".$consumer_key."&oauth_nonce=".$oauth_nonce."&oauth_signature_method=".$sig_method."&oauth_timestamp=".$timestamp."&oauth_version=".$oauth_version;

// basestring должна содержать все переменные, которые будут передаваться. Эта переменная используется для генерации подписи

 $basestring = "GET&".urlencode($request_token_url)."&".urlencode($basestring);
 $hash_key = $consumer_secret."&";

// во время авторизации в $hash_key используется только $consumer_secret

 $oauth_signature = base64_encode(hash_hmac('sha1', $basestring, $hash_key, true));
 
 $url = $request_token_url."?oauth_nonce=".$oauth_nonce."&oauth_timestamp=".$timestamp."&oauth_consumer_key=".$consumer_key."&oauth_signature_method=".$sig_method."&oauth_version=".$oauth_version."&oauth_signature=".$oauth_signature."&oauth_callback=".$callback_url;

 if( $curl = curl_init() ) {
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
  $out = curl_exec($curl);
  $aOut = array();
  foreach(explode("&", $out) as $key=>$value){
   list($k,$v) = explode("=", $value);
   $aOut[$k] = $v;
   if($k == "oauth_token_secret"){
    $recent_update = mysql_query("UPDATE users SET oauth_token_secret='".$v."' WHERE user_id=".$_SESSION['user_id']);
    мы сохраняем oauth_token_secret, так как нам эта переменная понадобится на третьем шаге для генерации oauth_signature, но после получения access_token мы ее перезапишем
   }
  }
  echo json_encode($aOut);
  curl_close($curl);
 }
}

Этап 2

Первый этап закончен и происходит редирект для авторизации приложения. Если пользователь нажимает «YES», то происходит еще один редирект и в GET передаются oauth_token, который все еще request_token и oauth_verifier, который нам понадобится для получения access_token на третьем этапе.

Этап 3

Ниже код получения access_token

if(isset($_GET["oauth_token"])){
 $recent_update = mysql_query("UPDATE users SET oauth_verifier='".$_GET['oauth_verifier']."' WHERE user_id=".$_SESSION['user_id']);
 $recent = mysql_query("SELECT * FROM users WHERE user_id=".$_SESSION['user_id']);
 $recent_info = mysql_fetch_assoc($recent);
 
 $request_token_url = "http://www.flickr.com/services/oauth/access_token";
 $oauth_nonce=md5(microtime().mt_rand());
 $timestamp = time();
 $consumer_key = "676d28f0d2ae990730a3fb232c252a8b";
 $consumer_secret = "36b056c53456fef";
 $sig_method = "HMAC-SHA1";
 $oauth_version = "1.0";
 $oauth_token_secret = $recent_info['oauth_token_secret'];

 $basestring = "oauth_consumer_key=".$consumer_key."&oauth_nonce=".$oauth_nonce."&oauth_signature_method=".$sig_method."&oauth_timestamp=".$timestamp."&oauth_token=".$_GET['oauth_token']."&oauth_verifier=".$_GET['oauth_verifier']."&oauth_version=".$oauth_version;
 $basestring = "GET&".urlencode($request_token_url)."&".urlencode($basestring);

// здесь уже $hash_key из двух переменных собирается
 $hash_key = $consumer_secret."&".$oauth_token_secret;
 $oauth_signature = base64_encode(hash_hmac('sha1', $basestring, $hash_key, true));

 $url = $request_token_url."?oauth_nonce=".$oauth_nonce."&oauth_timestamp=".$timestamp."&oauth_verifier=".$_GET['oauth_verifier']."&oauth_consumer_key=".$consumer_key."&oauth_signature_method=".$sig_method."&oauth_version=".$oauth_version."&oauth_token=".$_GET['oauth_token']."&oauth_signature=".$oauth_signature;

 if( $curl = curl_init() ) {
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
  $out = curl_exec($curl);
  $aOut = array();
  foreach(explode("&", $out) as $key=>$value){
   list($k,$v) = explode("=", $value);
   $aOut[$k] = $v;
   if($k == "oauth_token"){
    $recent_update = mysql_query("UPDATE users SET oauth_token='".$v."' WHERE user_id=".$_SESSION['user_id']);
   }
   if($k == "oauth_token_secret"){
    $recent_update = mysql_query("UPDATE users SET oauth_token_secret='".$v."' WHERE user_id=".$_SESSION['user_id']);
   }
  }
  echo json_encode($aOut);
  curl_close($curl);
 }
}

полученные здесь oauth_token и oauth_token_secret потребуются для выполнения всех последующих запросов

Получение списка фотографий

Если использовать OAUTH авторизацию на Flickr, то методы описанные по адресу www.flickr.com/services/api/ не работают. Точнее работают, но нужно внести некоторые корректировки.

Ниже пример вывода списка фотографий одного пользователя.

// url не такой как в документации
$request_url = "http://www.flickr.com/services/rest";
$oauth_nonce=md5(microtime().mt_rand());
$timestamp = time();
$consumer_key = "676d28f023уe990730a3fbc12c252a8b";
$consumer_secret = "36b05634d0626fef";
$sig_method = "HMAC-SHA1";
$oauth_version = "1.0";

// это две переменные полученные на третьем шагеавторизации
$oauth_token = "72157630222363050-c9347c35c6f40906";
$oauth_token_secret = "568455560efe6e4e";

$format = "json";
$method = "flickr.photos.search";
$user_id = "22227268@N03";

$basestring = "format=".$format."&method=".$method."&oauth_consumer_key=".$consumer_key."&oauth_nonce=".$oauth_nonce."&oauth_signature_method=".$sig_method."&oauth_timestamp=".$timestamp."&oauth_token=".$oauth_token."&oauth_version=".$oauth_version."&user_id=".$user_id;
$basestring = "GET&".urlencode($request_url)."&".urlencode($basestring);

$hash_key = $consumer_secret."&".$oauth_token_secret;
$oauth_signature = base64_encode(hash_hmac('sha1', $basestring, $hash_key, true));

$url = $request_url."?format=".$format."&method=".$method."&oauth_consumer_key=".$consumer_key."&oauth_nonce=".$oauth_nonce."&oauth_signature_method=".$sig_method."&oauth_timestamp=".$timestamp."&oauth_token=".$oauth_token."&oauth_version=".$oauth_version."&oauth_signature=".$oauth_signature."&user_id=".$user_id;

if( $curl = curl_init() ) {
 curl_setopt($curl, CURLOPT_URL, $url);
 curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
 $out = curl_exec($curl);
 echo $out;
 curl_close($curl);
}

Автор: Zavada

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js