Авторизация на сайте через twitter (PHP)

Вступление

Авторизация на сайте через твиттер происходит в 5 этапов:

  1. Регистрация приложения и получение секретных ключей;
  2. Отправка запроса на request_token и получение двух токенов: oauth_token и oauth_token_secret;
  3. Авторизация пользователя или подтверждение пользователя, что он доверяет вашему приложению (authorize);
  4. Получение идентификатора пользователя (access_token);
  5. Получение данных пользователя с Твиттера.

Все примеры на языке программирования PHP.

Для тех кто не любит читать мануалы и документацию, предлагаю перейти сразу к наглядному примеру:

С текстовым сопровождением: http://expange.ru/files/130/twitter_auth.php (Все строки и подписи выводятся на экран, происходит авторизация приложения и вывод данных пользователя на экран).

Без текстового сопровождения: http://expange.ru/files/130/twitter_auth_nodebug.php (Происходит авторизация приложения и вывод данных пользователя на экран).

Скачать архив: TwitterAuth.rar 3,57Кб.

Более или менее подготовленный PHP-программист должен легко разобраться, класс для авторизации очень простой.

Регистрация приложения

Переходим по ссылке: https://dev.twitter.com/apps/new и создаем новое приложение.

Необходимо заполнить следующие поля:

  • Название приложения;
  • Описание — краткое описание вашего приложения;
  • Сайт — сайт с которого будет производиться авторизация;
  • callback-страница — страница на которую будет произведен «редирект» после авторизации.

Создание приложения (twitter)

После заполнения всех полей создается приложение и вы попадаете на страницу с секретными ключами (Consumer key, Consumer secret).

Consumer key, Consumer secret

Созданное приложение (twitter)

Для секретных ключей определяем соответствующие константы. Например:

1
2
3
4
5
6
7
8
9
10
<?php
define 
('TWITTER_CONSUMER_KEY''O0IgnYHonW4KGL6pJr0YCQ');
define ('TWITTER_CONSUMER_SECRET''OYUjBgJPl4yra3N32sSpSSVGboLSCo5pLGsky20VJE');
define ('TWITTER_URL_CALLBACK''http://expange.ru/twitter_auth.php?auth=1');

define ('URL_REQUEST_TOKEN''https://api.twitter.com/oauth/request_token');
define ('URL_AUTHORIZE''https://api.twitter.com/oauth/authorize');
define ('URL_ACCESS_TOKEN''https://api.twitter.com/oauth/access_token');
define ('URL_ACCOUNT_DATA''https://api.twitter.com/1.1/users/show.json');
?>

request_token

Наверное самый сложный пункт — одно неверное движение и застрянете здесь надолго. Очень много тонкостей, которые нужно соблюдать при формировании секретной подписи (oauth_signature). Именно этот пункт вызывает много вопросов у пользователей, как при формировании строки для кодирования так и получения подписи oauth_signature.

Читайте очень внимательно.

Данный этап разделен на 4! подэтапа:

  1. Сформировать строку;
  2. Получить хэш-код сформированной строки функцией hash_hmac(), полученный хэш закодировать функцией base64_encode();
  3. Сформировать GET-запрос по адресу: https://api.twitter.com/oauth/request_token;
  4. Получить результат GET-запроса (можно использовать curl или file_get_contents).

Формирование строки (base_string)

При формировании строки самое главное соблюсти порядок расположения параметров, т.к. из склеенная строки будет формироваться хэш-код.

Формат строки:

Т.к. пример на PHP, строку буду формировать как удобнее программисту.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

// рандомная строка (для безопасности)
$oauth_nonce md5(uniqid(rand(), true)); // ae058c443ef60f0fea73f10a89104eb9

// время когда будет выполняться запрос (в секундых)
$oauth_timestamp time(); // 1310727371

/**
 * Константы смотрите чуть повыше
 *
 * Обратите внимание на использование функции urlencode и расположение амперсандов.
 * Если поменяете положение параметров oauth_... или уберете где-нибудь urlencode - получите ошибку
 *
 */
$oauth_base_text "GET&";
$oauth_base_text .= urlencode(URL_REQUEST_TOKEN)."&";
$oauth_base_text .= urlencode("oauth_callback=".urlencode(TWITTER_URL_CALLBACK)."&");
$oauth_base_text .= urlencode("oauth_consumer_key=".TWITTER_CONSUMER_KEY."&");
$oauth_base_text .= urlencode("oauth_nonce=".$oauth_nonce."&");
$oauth_base_text .= urlencode("oauth_signature_method=HMAC-SHA1&");
$oauth_base_text .= urlencode("oauth_timestamp=".$oauth_timestamp."&");
$oauth_base_text .= urlencode("oauth_version=1.0");

/**
 * В результате получим строку, такого вида:

GET&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&
oauth_callback%3Dhttp%253A%252F%252Fexpange.ru%252Ftwitter_auth.php%253Fauth%253D1%26
oauth_consumer_key%3DO0IgnYHonW4KGL6pJr0YCQ%26
oauth_nonce%3Dae058c443ef60f0fea73f10a89104eb9%26
oauth_signature_method%3DHMAC-SHA1%26
oauth_timestamp%3D1310727371%26
oauth_version%3D1.0

 * Естественно строка должны быть однострочной (переносы сделаны для удобства сравнения)
 */
?>

Хэш-код (hash_hmac, base64_encode)

В функцию hash_hmac() передаются 4 параметра: алгоритм, строка, ключ, булево значение — true.

Алгоритм — sha1, строка была сформирована выше.

Ключ

Ключ имеет следующее значение: Consumer secret + знак амперсанда.

1
2
3
4
5
6
7
8
9
<?php

$key 
TWITTER_CONSUMER_SECRET."&"// На конце должен быть амперсанд & !!!
// key: OYUjBgJPl4yra3N32sSpSSVGboLSCo5pLGsky20VJE&

$oauth_signature base64_encode(hash_hmac("sha1"$oauth_base_text$keytrue));
// oauth_signature: BB6w/jAdrHQD1/iUqqEZiI8o2M0=

?>

GET-запрос request_token

И так параметр oauth_signature мы сформировали. Осталось сформировать GET-запрос, получить результат его выполнения и получить заветные токены: oauth_token и  oauth_token_secret.

GET-запрос будет выглядеть следующим образом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php
/**
 * Опять же внимательно смотрим на функцию urlencode
 *
 */
$url URL_REQUEST_TOKEN;
$url .= '?oauth_callback='.urlencode(TWITTER_URL_CALLBACK);
$url .= '&oauth_consumer_key='.TWITTER_CONSUMER_KEY;
$url .= '&oauth_nonce='.$oauth_nonce;
$url .= '&oauth_signature='.urlencode($oauth_signature);
$url .= '&oauth_signature_method=HMAC-SHA1';
$url .= '&oauth_timestamp='.$oauth_timestamp;
$url .= '&oauth_version=1.0';
/**
 * Строка запроса (Переносы строк естественно не нужны):

https://api.twitter.com/oauth/request_token
?oauth_callback=http%3A%2F%2Fexpange.ru%2Ftwitter_auth.php%3Fauth%3D1
&oauth_consumer_key=O0IgnYHonW4KGL6pJr0YCQ
&oauth_nonce=ae058c443ef60f0fea73f10a89104eb9
&oauth_signature=BB6w%2FjAdrHQD1%2FiUqqEZiI8o2M0%3D
&oauth_signature_method=HMAC-SHA1
&oauth_timestamp=1310727371
&oauth_version=1.0

**/


/**
 * Получить результат GET-запроса будем функцией file_get_contents
 * можно и даже лучше использовать curl, но здесь и эта функция справляется отлично
 *
 */
$response file_get_contents($url);
// если все сделано правильно, $response будет содержать нечто подобное:
// oauth_token=DZmWEaKh7EqOJKScI48IgYMxYyFF2riTyD5N9wqTA&oauth_token_secret=NuAL0AvzocI9zxO7VnVPrNEcb9EW8kwpwJmcqg5pMWg&oauth_callback_confirmed=true
//
// Если что-то не так, будет выведено следующее:
// Failed to validate oauth signature and token
// Самая распространенная ошибка, означающая, что в большинстве случаев
// подпись oauth_signature сформирована неправильно.
// Еще раз внимательно просмотрите как формируется строка и кодируется oauth_signature,
// сверьте с примером использования функций urlencode

// И так все выведено правильно. Разбираем полученную строку.

parse_str($response$result);
/**
 * $result:
Array
(
    [oauth_token] => DZmWEaKh7EqOJKScI48IgYMxYyFF2riTyD5N9wqTA
    [oauth_token_secret] => NuAL0AvzocI9zxO7VnVPrNEcb9EW8kwpwJmcqg5pMWg
    [oauth_callback_confirmed] => true
)
*/


// session_start вначале я думаю у вас вызывается
$_SESSION['oauth_token'] = $oauth_token $result['oauth_token'];
$_SESSION['oauth_token_secret'] = $oauth_token_secret $result['oauth_token_secret'];

?>

И так, если данные получены удачно, можно переходить к этапу номер 2.

Failed to validate oauth signature and token

Самая распространенная ошибка, означающая, что в большинстве случаев подпись oauth_signature сформирована неправильно.

Еще раз, внимательно просмотрите как формируется строка и кодируется oauth_signature, сверьте с примером использования функций urlencode.

authorize

Самый простой этап, нам нужно сформировать строку запроса и перейти по сформированному адресу.

1
2
3
4
5
6
<?php
$url 
URL_AUTHORIZE;
$url .= '?oauth_token='.$oauth_token;

// url: https://api.twitter.com/oauth/authorize?oauth_token=qexSk7ySxVV5DPr9j9zE0RuxT5Zxbp1rOPqemizeU
?>

Авторизация приложения

После перехода по адресу, попадаем на страницу авторизации приложения (т.е. пользователь доверяет вашему приложению).

Авторизация приложения (twitter)

После авторизации приложения происходит возврат на страницу TWITTER_URL_CALLBACK (http://expange.ru/twitter_auth.php?auth=1), в GET-запрос добавляется 2 параметра: &oauth_token=zzphuIadnjHpoYFv8crAwH67WR2gryp2s7y1AHphuw&oauth_verifier=9y1OPe6oGvDPSeTXHcWDmGUDY9I6d9RrFlz2YNJJRfc.

access_token

После возврата на страницу получили 2 GET-параметра:

  • oauth_token: zzphuIadnjHpoYFv8crAwH67WR2gryp2s7y1AHphuw
  • oauth_verifier: 9y1OPe6oGvDPSeTXHcWDmGUDY9I6d9RrFlz2YNJJRfc

Данный этап похож на этап request_token, так же понадобится сформировать oauth_nonce, oauth_timestamp, oauth_signature и выполнить GET-запрос, по определенному адресу.

Формирование строки (base_string)

Как и в пункте request_token, при формировании строки главное соблюсти порядок расположения параметров.

Формат строки:

Формирование строки сразу в качестве PHP-примера.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php

// Заново создаем oauth_nonce и oauth_timestamp
// рандомная строка (для безопасности)
$oauth_nonce md5(uniqid(rand(), true)); // c775a2221c0d3a187438628e8427f262

// время когда будет выполняться запрос (в секундых)
$oauth_timestamp time(); // 1310727378

// oauth_token
$oauth_token $_GET['oauth_token'];

// oauth_verifier
$oauth_verifier $_GET['oauth_verifier'];

// oauth_token_secret получаем из сессии, которую зарегистрировали
// во время запроса request_token
$oauth_token_secret $_SESSION['oauth_token_secret'];

/**
 * Обратите внимание на использование функции urlencode и расположение амперсандов.
 * Если поменяете положение параметров oauth_... или уберете где-нибудь urlencode - получите ошибку
 *
 */
$oauth_base_text "GET&";
$oauth_base_text .= urlencode(URL_ACCESS_TOKEN)."&";
$oauth_base_text .= urlencode("oauth_consumer_key=".TWITTER_CONSUMER_KEY."&");
$oauth_base_text .= urlencode("oauth_nonce=".$oauth_nonce."&");
$oauth_base_text .= urlencode("oauth_signature_method=HMAC-SHA1&");
$oauth_base_text .= urlencode("oauth_token=".$oauth_token."&");
$oauth_base_text .= urlencode("oauth_timestamp=".$oauth_timestamp."&");
$oauth_base_text .= urlencode("oauth_verifier=".$oauth_verifier."&");
$oauth_base_text .= urlencode("oauth_version=1.0");

/**
 * В результате получим строку, такого вида:

GET&https%3A%2F%2Fapi.twitter.com%2Foauth%2Faccess_token&
oauth_consumer_key%3DO0IgnYHonW4KGL6pJr0YCQ%26
oauth_nonce%3Dc775a2221c0d3a187438628e8427f262%26
oauth_signature_method%3DHMAC-SHA1%26
oauth_token%3DDZmWEaKh7EqOJKScI48IgYMxYyFF2riTyD5N9wqTA%26
oauth_timestamp%3D1310727378%26
oauth_verifier%3DEJxb8eSgNdiUZPwi5Qwwt7JPE13nfXpCXOZSwCqBU%26
oauth_version%3D1.0

 * Естественно строка должны быть однострочной (переносы сделаны для удобства сравнения)
 */
?>

Ключ

Ключ имеет следующее значение: Consumer secret + знак амперсанда + oauth_token_secret.

1
2
3
4
5
6
7
8
<?php
$key 
TWITTER_CONSUMER_SECRET."&".$oauth_token_secret;
// key: OYUjBgJPl4yra3N32sSpSSVGboLSCo5pLGsky20VJE&NuAL0AvzocI9zxO7VnVPrNEcb9EW8kwpwJmcqg5pMWg

$oauth_signature base64_encode(hash_hmac("sha1"$oauth_base_text$keytrue));
// oauth_signature: WqIpf1g6fEdNk67Rc+cP9zxji5k=

?>

GET-запрос access_token

И так параметр oauth_signature мы сформировали. Осталось сформировать GET-запрос, получить результат его выполнения и получить заветные токены: oauth_token и  oauth_token_secret.

GET-запрос будет выглядеть следующим образом:

Старый нерабочий кусок кода

$url = URL_REQUEST_TOKEN;

$url .= '?oauth_callback='.urlencode(TWITTER_URL_CALLBACK);

$url .= '&oauth_consumer_key='.TWITTER_CONSUMER_KEY;

$url .= '&oauth_nonce='.$oauth_nonce;

$url .= '&oauth_signature='.urlencode($oauth_signature);

$url .= '&oauth_signature_method=HMAC-SHA1';

$url .= '&oauth_timestamp='.$oauth_timestamp;

$url .= '&oauth_version=1.0';

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
/**
 * Опять же внимательно смотрим на функцию urlencode
 *
 */
$url URL_ACCESS_TOKEN;
$url .= '?oauth_nonce='.$oauth_nonce;
$url .= '&oauth_signature_method=HMAC-SHA1';
$url .= '&oauth_timestamp='.$oauth_timestamp;
$url .= '&oauth_consumer_key='.TWITTER_CONSUMER_KEY;
$url .= '&oauth_token='.urlencode($oauth_token);
$url .= '&oauth_verifier='.urlencode($oauth_verifier);
$url .= '&oauth_signature='.urlencode($oauth_signature);
$url .= '&oauth_version=1.0';

/**
 * Строка запроса $url (Переносы строк естественно не нужны):

https://api.twitter.com/oauth/access_token
?oauth_nonce=c775a2221c0d3a187438628e8427f262
&oauth_signature_method=HMAC-SHA1
&oauth_timestamp=1310727378
&oauth_consumer_key=O0IgnYHonW4KGL6pJr0YCQ
&oauth_token=DZmWEaKh7EqOJKScI48IgYMxYyFF2riTyD5N9wqTA
&oauth_verifier=EJxb8eSgNdiUZPwi5Qwwt7JPE13nfXpCXOZSwCqBU
&oauth_signature=WqIpf1g6fEdNk67Rc%2BcP9zxji5k%3D
&oauth_version=1.0

**/

/**
 * Получить результат GET-запроса будем функцией file_get_contents
 * можно и даже лучше использовать curl, но здесь и эта функция справляется отлично
 */

$response file_get_contents($url);
// если все сделано правильно, $response будет содержать нечто подобное:
// oauth_token=228497030-pmcYm211OCBvlRnLBA9pjbtpKtMQ7ofghRwWJYlA&oauth_token_secret=IyZ5SFgTfRWtluEyavSAkUi8MJMgdYCZUlt5aNNMg&user_id=228497030&screen_name=expange

// Разбираем полученную строку.
parse_str($response$result);
/**
 * $result:
Array
(
    [oauth_token] => 228497030-pmcYm211OCBvlRnLBA9pjbtpKtMQ7ofghRwWJYlA
    [oauth_token_secret] => IyZ5SFgTfRWtluEyavSAkUi8MJMgdYCZUlt5aNNMg
    [user_id] => 228497030
    [screen_name] => expange
)
*/

?>

Самое главное мы получили — user_id, и то, что этот user_id на самом деле тот за кого себя выдает.

Данные Твиттер-пользователя

У многих, кто продолжал использовать версию 1.0 стала появляться ошибка Bad Authentication Data, с кодом 215. С переходом твиттера с версии 1.0 на версию 1.1, усложнилось получение данных пользователя. Теперь необходимо генерировать подпись из параметров запроса.

  1. oauth_token получили в прошлом запросе
  2. oauth_token_secret получили в прошлом запросе
  3. Сформировать строку GET-запроса;
  4. Получить и обработать данные.

Адрес запроса

Теперь данные возвращаются только в JSON формате:
https://api.twitter.com/1.1/users/show.json?screen_name=<SCREEN_NAME>

Помимо этого нужно сформировать подпись.

Пример api.twitter.com/1.1/users/show.json

Формат адреса: https://api.twitter.com/1.1/users/show.json?screen_name=expange

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php

// Заново создаем oauth_nonce и oauth_timestamp
// рандомная строка (для безопасности)
$oauth_nonce md5(uniqid(rand(), true));

// время когда будет выполняться запрос (в секундых)
$oauth_timestamp time();

$oauth_token $result['oauth_token'];
$oauth_token_secret $result['oauth_token_secret'];
$screen_name $result['screen_name'];

$oauth_base_text "GET&";
$oauth_base_text .= urlencode(URL_ACCOUNT_DATA).'&';
$oauth_base_text .= urlencode('oauth_consumer_key='.TWITTER_CONSUMER_KEY.'&');
$oauth_base_text .= urlencode('oauth_nonce='.$oauth_nonce.'&');
$oauth_base_text .= urlencode('oauth_signature_method=HMAC-SHA1&');
$oauth_base_text .= urlencode('oauth_timestamp='.$oauth_timestamp."&");
$oauth_base_text .= urlencode('oauth_token='.$oauth_token."&");
$oauth_base_text .= urlencode('oauth_version=1.0&');
$oauth_base_text .= urlencode('screen_name=' $screen_name);

$key TWITTER_CONSUMER_SECRET '&' $oauth_token_secret;
$signature base64_encode(hash_hmac("sha1"$oauth_base_text$keytrue));

// Формируем GET-запрос
$url URL_ACCOUNT_DATA;
$url .= '?oauth_consumer_key=' TWITTER_CONSUMER_KEY;
$url .= '&oauth_nonce=' $oauth_nonce;
$url .= '&oauth_signature=' urlencode($signature);
$url .= '&oauth_signature_method=HMAC-SHA1';
$url .= '&oauth_timestamp=' $oauth_timestamp;
$url .= '&oauth_token=' urlencode($oauth_token);
$url .= '&oauth_version=1.0';
$url .= '&screen_name=' $screen_name;

// делаем запрос
$response file_get_contents($url);

// разбираем запрос
$user_data json_decode($response);

echo 
'<pre>';
print_r($user_data);
echo 
'</pre>';

/** Результат в виде объекта будет примерно следующего содержания:

stdClass Object
(
    [default_profile_image] => 
    [profile_background_tile] => 
    [protected] => 
    [default_profile] => 
    [contributors_enabled] => 
    [url] => http://expange.ru
    [name] => expange.ru
    [id_str] => 228497030
    [is_translator] => 
    [show_all_inline_media] => 1
    [geo_enabled] => 
    [profile_link_color] => 1F98C7
    [follow_request_sent] => 
    [utc_offset] => 10800
    [created_at] => Sun Dec 19 22:12:45 +0000 2010
    [friends_count] => 2
    [profile_sidebar_border_color] => C6E2EE
    [following] => 
    [time_zone] => Moscow
    [profile_image_url] => http://a3.twimg.com/profile_images/1228124572/expange_normal.png
    [description] => 
    [statuses_count] => 106
    [profile_use_background_image] => 1
    [favourites_count] => 0
    [status] => stdClass Object
        (
            [place] => 
            [truncated] => 
            [id_str] => 91646116151570432
            [in_reply_to_status_id] => 
            [text] => Авторизация на сайте через twitter (PHP) http://t.co/SRtztLi via @expange
            [created_at] => Thu Jul 14 23:11:51 +0000 2011
            [geo] => 
            [favorited] => 
            [in_reply_to_status_id_str] => 
            [coordinates] => 
            [id] => 91646116151570432
            [in_reply_to_screen_name] => 
            [source] => Tweet Button
            [in_reply_to_user_id_str] => 
            [in_reply_to_user_id] => 
            [contributors] => 
            [retweeted] => 
            [retweet_count] => 0
        )

    [verified] => 
    [profile_background_color] => C6E2EE
    [screen_name] => expange
    [listed_count] => 0
    [profile_background_image_url] => http://a1.twimg.com/images/themes/theme2/bg.gif
    [id] => 228497030
    [notifications] => 
    [profile_background_image_url_https] => https://si0.twimg.com/images/themes/theme2/bg.gif
    [profile_text_color] => 663B12
    [lang] => en
    [profile_sidebar_fill_color] => DAECF4
    [followers_count] => 1
    [profile_image_url_https] => https://si0.twimg.com/profile_images/1228124572/expange_normal.png
    [location] => Moscow
)

**/

?>

Все. Данные пользователя получены, и есть уверенность, что это реальный Твиттер-пользователь, а не подставной.

Обработка данных для авторизации уже дело техники и вам решать как с ними поступить.

Дополнительные данные

Ссылка на документацию Твиттера: https://dev.twitter.com/docs/auth/oauth

Опубликовано: 24 октября 2013  ·  Автор: Артём Фёдоров  ·  22838 просмотров

Полезные статьи по теме

Категория

ГлавнаяИнтернетБлогиTwitterАвторизация на сайте через twitter (PHP)

Чтобы оставить комментарий нужно авторизоваться на сайте
или войти через ВКонтакте или Фейсбук

Войти через ФейсбукВойти через Твиттер

Комментарии

Коментарии работают тут отвратительно, удалите мой дублирующий. Хотел добавить листинг, чтоб возвращался email - не дает.
Сергей Фединяк · 301 день назад
Необходимо передать параметр include_email=true и по адресу define URL_ACCOUNT_DATA = api.twitter.com/1.1/account/verify_credentials.json
Сергей Фединяк · 301 день назад
Данный пример не возвращает email пользователя
Сергей Фединяк · 301 день назад
Данный пример не возвращает email пользователя
Сергей Фединяк · 301 день назад
Автору огромный респект!Большое спасибо!!!!!!!
· 1 год назад
Автору огромный респект!Большое спасибо!!!!!!!
· 1 год назад
Олег, а на какую страницу редирект происходит?
· 3 года назад
А у меня после получения токена при переводе пользователя на страницу авторизация приложения в твитере пишет, что такой страницы на твитере не существует. Из-за чего такая ошибка может быть?
Олег Юрчик · 3 года назад
Огромное спасибо за подробнейшее руководство! :)
П.С. Радует, что спустя почти год, алгоритм по прежнему актуален
· 3 года назад
пардон. все получилось. забыл убрать отладочную информацию.
Руслан Шакиров · 3 года назад
Twitter, Блоги, Интернет

© 2010-2017 expange.ru
При полном или частичном копировании статей сайта, ссылка на источник обязательна.

Хотите узнать больше информации, пишите на: artem@expange.ru

Полезное онлайн  ·  Новости  ·  Изображения  ·  Статьи по датам

О проекте  ·  Правила пользования  ·  Представительства

Благодарности и пожелания