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

Website developmentPHPAPI
Sandbox
Документация по 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);
}
Tags:flickrflickr apioauth 2.0
Hubs: Website development PHP API
0
3.4k 15
Comments 5

Popular right now

Team Lead 2.0
January 28, 202190,000 ₽OTUS
Комплексное обучение PHP
April 19, 202120,000 ₽Loftschool
PHP. Уровень 1. Основы создания сайтов
February 1, 202115,990 ₽Специалист.ру
Product Manager IT-проектов
January 28, 202160,000 ₽OTUS
JavaScript Developer. Professional
January 28, 202170,000 ₽OTUS