OAuth авторизация через Одноклассники.ру

OAuth авторизация через Одноклассники.ру

iSergium

Одноклассники - популярная российская социльная сеть, шестой по посещаемости сайт рунета (данные на июль 2013). За своё семилетнее существование сайт подвергся немалому количеству критики, стал объектом сотен приколов и даже получил премию "разочарование года" в конкурте РОТОР в 2009 году. Но это не мешает ему иметь более 200 млн. зарегистрированных пользователей и посещаемость более 35 млн. посетителей в сутки.

ok

С чего начать

Система составления адресов у Одноклассников странная, потому прямой постоянной ссылки на регистрацию нет. Но любой неавторизованный пользователь, пройдя на главную страницу, без проблем справится с регистрацией. После отправки формы регистрации профиль создается сразу, но для подтверждения email проверьте свою почту.

Запросить права разработчика необходимо здесь. Добавление приложения здесь. После добавления приложения на почту придет письмо с id приложения, публичным и секретным ключами. Это значит, что можно приступать к следующему шагу.

Если ссылки не работают, значит ok.ru вновь перелопалили документацию и нужно копать здесь: apiok.ru

Чем продолжить

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

Как всегда, сначала определяем константы.

class OAuthOK {
    const APP_ID = 12345678; //ID приложения
    const APP_PUBLIC = 'sometestapppublic'; //Публичный ключ
    const APP_SECRET = 'sometestappsecret'; //Защищенный ключ
    const URL_CALLBACK = 'http://example.com/oauth/ok.php'; //URL, на который произойдет перенаправление после авторизации
}

Перенаправление пользователя на авторизацию и подтверждение доступа приложению:

class OAuthOK {
    const URL_AUTHORIZE = 'http://www.odnoklassniki.ru/oauth/authorize';
    public static function goToAuth()
    {
        Utils::redirect(self::URL_AUTHORIZE .
            '?client_id=' . self::APP_ID .
            '&response_type=code' .
            '&redirect_uri=' . urlencode(self::URL_CALLBACK));
    }
}

Если при таком переходе на одноклассников Вы видите текст "Вы не активировали свой аккаунт на Одноклассниках", то Вам еще престоит поделиться номером своего мобильного телефона. Добавить его можно в настройках профиля.

Активированные пользователи пойдут дальше. При какой-либо ошибке пользователя перебросит на OK_URL_CALLBACK?error=xxx. При удачном исходе происходит редирект OK_URL_CALLBACK?code=xxx. То есть, логика здесь стандартная:

if (!empty($_GET['error'])) {
    // Пришёл ответ с ошибкой.
} elseif (empty($_GET['code'])) {
    // Самый первый запрос. Отправляем пользователя на авторизацию
    OAuthOK::goToAuth();
} else {
    // Ответ пришёл удачный
    // Запрос токена и данных пользователя
}

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

class OAuthOK {
    const URL_GET_TOKEN = 'http://api.odnoklassniki.ru/oauth/token.do';
    const URL_ACCESS_TOKEN = 'http://api.odnoklassniki.ru/fb.do';
    private static $token;
    public static $userId;
    public static $userData;
 
    public static function getToken($code) {
 
        $data = array(
            'code' => trim($code),
            'redirect_uri' => self::URL_CALLBACK,
            'client_id' => self::APP_ID,
            'client_secret' => self::APP_SECRET,
            'grant_type' => 'authorization_code'
        );
 
        $opts = array('http' =>
            array(
                'method' => 'POST',
                'header' =>"Content-type: application/x-www-form-urlencoded\r\n".
                    "Accept: */*\r\n",
                'content' => http_build_query($data)
            )
        );
 
        if (!($response = @file_get_contents(self::URL_GET_TOKEN, false, stream_context_create($opts)))) {
            return false;
        }
 
        $result = json_decode($response);
        if (empty($result->access_token)) {
            return false;
        }
 
        self::$token = $result->access_token;
 
        return true;
    }
 
    public static function getUser() {
 
        if (!self::$token) {
            return false;
        }
 
        $url = self::URL_ACCESS_TOKEN .
            '?access_token=' . self::$token .
            '&method=users.getCurrentUser' .
            '&application_key=' . self::APP_PUBLIC .
            '&sig=' . md5('application_key=' . self::APP_PUBLIC . 'method=users.getCurrentUser' . md5(self::$token . self::APP_SECRET));
 
        if (!($response = @file_get_contents($url))) {
            return false;
        }
 
        $user = json_decode($response);
 
        if (empty($user)) {
            return false;
        }
 
        self::$userId = $user->uid;
        return self::$userData = $user;
    }
}

$userData будет примерно таким:

stdClass Object
(
    [uid] => 123456789
    [birthday] => 1989-06-11
    [age] => 24
    [first_name] => Name
    [last_name] => Surname
    [name] => Name Surname
    [locale] => ru
    [gender] => male
    [has_email] => 1
    [location] => stdClass Object
        (
            [country] => RUSSIAN_FEDERATION
            [city] => Новосибирск
        )
 
    [current_status] => Modern Talking - CHERI CHERI LADY
    [current_status_id] => 61545962640678
    [current_status_date] => 2013-03-21 15:33:16
    [online] => web
    [photo_id] => 503968900646
    [pic_1] => http://i502.mycdn.me/getImage?photoId=503968900646&photoType=4
    [pic_2] => http://usd3.mycdn.me/getImage?photoId=503968900646&photoType=2
)

Изображение pic_1 имеет размер 50х50, pic_2 отмасштабировано по максимальной стороне 128 (в моем случае 96х128). Остальные поля или ненужные или в пояснении не нуждаются. Если возникли вопросы, то подробное описание метода находится по этой ссылке.

одноклассники

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

Комментарии

Alex Gorodok 16.09.2015 14:04:41
Сайт - бомба. Единственное чего не хватает - OAuth для Twitter((