OAuth авторизация через Twitter

OAuth авторизация через Twitter

iSergium

Twitter - это настолько популярный сервис, что в некоторых языках стал нарицательным. Этот крупнейший сервис микроблогинга имеет более полумиллиарда зарегистрированных пользователей. Эта солидная цифра является хорошей причиной прикрутить авторизацию через Twitter на Вашем сайте.

tweet retweet

Подготовка.

Регистрация в сервисе - дело простейшее.

Далее создание приложения. Никаких прав разработчика запрашивать не нужно, приложение можно сразу создавать по этой ссылке. Пункт "Callback URL" заполнять не обязательно - его можно передавать непосредственно в запросах. Из самого приложения самыми важными для работы данными являются Consumer Key (API Key) и Consumer Secret (API Secret), они находятся во вкладке "Keys and Access Tokens".

На apps.twitter.com можно увидеть список имеющихся приложений.

Процесс.

Основные определения были описаны в начале этой статьи, почитайте вступление, если еще не читали. Про redirect() было сказано здесь. Получившийся класс можно скачать ниже из раздела "дополнительно".

Сначала константы:

class OAuthTwitter {
    const CONSUMER_KEY = 'consumer_key';
    const CONSUMER_SECRET = 'consumer_secret';
    const URL_CALLBACK = 'http://example.com/oauth/twitter.php'; //URL, на который произойдет перенаправление после авторизации
}

Перенаправление на авторизацию здесь сложнее, чем у большинства, - сначала необходимо запросить токен и лишь потом отправить пользователя на подтверждение доступа. Все запросы токенов дополнительно требуют захэшированных параметров, этот хэш отправляется в поле oauth_signature. Само хэширование вынесено в метод encode. Параметр oauth_nonce - это уникальный маркер запроса, служит для защиты от повторных запросов с тем же набором параметров. Также внимания заслуживает параметр oauth_timestamp - если передаваемое в нём время сильно отличается от актуального, то запрос будет отклонён Твиттером, так что проверьте время сервера. Полученное значение oauth_token_secret позже понадобится при запросе токена доступа (это уже другой токен), потому оно записывается в $_SESSION.

class OAuthTwitter {
    const URL_REQUEST_TOKEN = 'https://api.twitter.com/oauth/request_token';
    const URL_AUTHORIZE = 'https://api.twitter.com/oauth/authorize';
    public static function goToAuth() {
        $oauth_nonce = md5(uniqid(rand(), true));
        $oauth_timestamp = time();
 
        $oauth_base_text = "GET&" .
            urlencode(self::URL_REQUEST_TOKEN) . "&" .
            urlencode(
                "oauth_callback=" . urlencode(self::URL_CALLBACK) . "&" .
                "oauth_consumer_key=" . self::CONSUMER_KEY . "&" .
                "oauth_nonce=" . $oauth_nonce . "&" .
                "oauth_signature_method=HMAC-SHA1&" .
                "oauth_timestamp=" . $oauth_timestamp . "&" .
                "oauth_version=1.0"
            );
 
        $key = self::CONSUMER_SECRET . "&";
        $oauth_signature = self::encode($oauth_base_text, $key);
 
        $url = self::URL_REQUEST_TOKEN .
            '?oauth_callback=' . urlencode(self::URL_CALLBACK) .
            '&oauth_consumer_key=' . self::CONSUMER_KEY .
            '&oauth_nonce=' . $oauth_nonce .
            '&oauth_signature=' . urlencode($oauth_signature) .
            '&oauth_signature_method=HMAC-SHA1' .
            '&oauth_timestamp=' . $oauth_timestamp .
            '&oauth_version=1.0';
 
        if (!($response = @file_get_contents($url))) {
            return false;
        }
        parse_str($response, $result);
 
        if (empty($result['oauth_token_secret'])) {
            return false;
        }
 
        $_SESSION['oauth_token_secret'] = $result['oauth_token_secret'];
 
        \Utils::redirect(self::URL_AUTHORIZE . '?oauth_token=' . $result['oauth_token']);
        return true;
    }
 
    private static function encode($string, $key) {
        return base64_encode(hash_hmac("sha1", $string, $key, true));
    }
}

Далее пользователь подтверждает или отклоняет доступ приложению к своему аккаунту. В любом случае произойдёт перенаправление на URL_CALLBACK. Логика не отличается от остальных сервисов:

if (!empty($_GET['denied'])) {
    // Пользователь отклонил доступ
    die('denied');
} elseif (empty($_GET['oauth_token']) || empty($_GET['oauth_verifier'])) {
    // Самый первый запрос
    OAuthTwitter::goToAuth();
} else {
    // Ответ пришёл удачный
    // Запрос токена доступа и данных пользователя
}

Запрос токена доступа и данных пользователя, вновь с encode:

class OAuthTwitter {
    const URL_GET_TOKEN = 'https://api.twitter.com/oauth2/token';
    const URL_ACCESS_TOKEN = 'https://api.twitter.com/oauth/access_token';
    const URL_USER_DATA = 'https://api.twitter.com/1.1/users/show.json';
 
    private static $token;
    public static $userId;
    public static $userData;
 
    public static function getToken($oauth_token, $oauth_verifier) {
        $oauth_nonce = md5(uniqid(rand(), true));
        $oauth_timestamp = time();
        $oauth_token_secret = $_SESSION['oauth_token_secret'];
 
        $oauth_base_text = "GET&" .
            urlencode(self::URL_ACCESS_TOKEN) . "&" .
            urlencode(
                "oauth_consumer_key=" . self::CONSUMER_KEY . "&" .
                "oauth_nonce=" . $oauth_nonce . "&" .
                "oauth_signature_method=HMAC-SHA1&" .
                "oauth_token=" . $oauth_token . "&" .
                "oauth_timestamp=" . $oauth_timestamp . "&" .
                "oauth_verifier=" . $oauth_verifier . "&" .
                "oauth_version=1.0"
            );
 
        $key = self::CONSUMER_SECRET . "&" . $oauth_token_secret;
        $oauth_signature = self::encode($oauth_base_text, $key);
 
        $url = self::URL_ACCESS_TOKEN .
            '?oauth_consumer_key=' . self::CONSUMER_KEY .
            '&oauth_nonce=' . $oauth_nonce .
            '&oauth_signature_method=HMAC-SHA1' .
            '&oauth_token=' . urlencode($oauth_token) .
            '&oauth_timestamp=' . $oauth_timestamp .
            '&oauth_verifier=' . urlencode($oauth_verifier) .
            '&oauth_signature=' . urlencode($oauth_signature) .
            '&oauth_version=1.0';
 
        if (!($response = @file_get_contents($url))) {
            return false;
        }
 
        parse_str($response, $result);
 
        if (empty($result['oauth_token']) || empty($result['user_id'])) {
            return false;
        }
 
        self::$token = $result['oauth_token'];
        self::$userId = $result['user_id'];
 
        return true;
    }
 
    public function getUser() {
        $data = array(
            'grant_type' => 'client_credentials',
        );
        $opts = array('http' =>
            array(
                'method' => 'POST',
                'header' =>"Content-type: application/x-www-form-urlencoded;charset=UTF-8\r\n" .
                    'Authorization: Basic ' . base64_encode(self::CONSUMER_KEY . ':' . self::CONSUMER_SECRET) . "\r\n",
                'content' => http_build_query($data)
            )
        );
        $context = stream_context_create($opts);
 
        if (!($response = @file_get_contents(self::URL_GET_TOKEN, false, $context))) {
            return false;
        }
        $result = json_decode($response, true);
 
        if (empty($result['access_token'])) {
            return false;
        }
 
        $opts = array('http' =>
            array(
                'method' => 'GET',
                'header' =>"Content-type: application/x-www-form-urlencoded;charset=UTF-8\r\n" .
                    'Authorization: Bearer ' . $result['access_token'] . "\r\n",
            )
        );
 
        $url = self::URL_USER_DATA . '?user_id=' . self::$userId;
        if (!($response = @file_get_contents($url, false, stream_context_create($opts)))) {
            return false;
        }
 
        $user = json_decode($response, true);
        if (empty($user)) {
            return false;
        }
 
        return self::$userData = $user;
    }
}

$userData содержит много данных: id, логин, имя, страна, последний статус и многое другое. Вот основные из них:

Array
(
    [id] => 783214
    [name] => Twitter
    [screen_name] => twitter
    [location] => San Francisco, CA 
    [description] => Your official source for news, updates and tips from Twitter, Inc.
 
Need help? Visit http://t.co/qq1HEzvnrA.
    [followers_count] => 50687704
    [friends_count] => 141
    [listed_count] => 89089
    [created_at] => Tue Feb 20 14:35:54 +0000 2007
    [favourites_count] => 137
    [utc_offset] => -28800
    [time_zone] => Pacific Time (US & Canada)
    [statuses_count] => 2313
    [lang] => en
    [profile_image_url] => http://pbs.twimg.com/profile_images/666407537084796928/YBGgi9BO_normal.png
)

Изображение по ссылке profile_image_url имеет разрешение 48х48.

 coddism.com twitter доступ

Дополнительно:

Комментарии

Александр Великий 29.05.2016 17:37:03
Сделай пожалуйста на instogram авторизацию