Авторизация на сайте через Яндекс

Авторизация на сайте через Яндекс

Сервис Яндекс.ID позволяет через API реализовать авторизацию пользователя на своем сайте. После разрешения доступа можно получить имя, фамилию, логин, e-mail и фото пользователя.

Для доступа к API нужно зарегистрировать приложение.

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

На странице https://oauth.yandex.ru/client/new указываются «Название приложения», другие поля не обязательны.

В платформах, нужно указать «Веб-сервисы» и указать в «Callback URI #1» адрес к PHP-скрипту, который будет обрабатывать авторизацию (например https://example.com/login_ya.php).

В разделе «Доступы», «API Яндекс.Паспорта» отметь нужные данные:

После отправки формы получим ID и пароль приложения.

Ссылка для входа

Сформируем и выведем ссылку, по которой пользователь будет проходить авторизацию. Значение параметра redirect_uri должно совпадать с Callback URI #1.

В параметре state можно передавать свои данные, которые вернутся в PHP-скрипт обработчика.

$params = array(
	'client_id'     => 'ID_ПРИЛОЖЕНИЯ',
	'redirect_uri'  => 'https://example.com/login_ya.php',
	'response_type' => 'code',
	'state'         => '123'
);
 
$url = 'https://oauth.yandex.ru/authorize?' . urldecode(http_build_query($params));
echo '<a href="'.$url.'">Авторизация через Яндекс</a>';

Если всё указано верно, то перейдя по ссылке откроется запрос на доступ:

Скрипт oauth_yandex.php

В скрипте получаем код авторизации, меняем его на токен и получаем данные пользователя.

Все запросы осуществляются методом POST, также Яндекс рекомендует передавать токен в HTTP заголовке Authorization, так он не сохранится в истории браузера.

<?php
$state = $_GET['state']; // 123
 
if (!empty($_GET['code'])) {
	// Отправляем код для получения токена (POST-запрос).
	$params = array(
		'grant_type'    => 'authorization_code',
		'code'          => $_GET['code'],
		'client_id'     => 'ID_ПРИЛОЖЕНИЯ',
		'client_secret' => 'ПАРОЛЬ_ПРИЛОЖЕНИЯ',
	);
	
	$ch = curl_init('https://oauth.yandex.ru/token');
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $params); 
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_HEADER, false);
	$data = curl_exec($ch);
	curl_close($ch);	
			 
	$data = json_decode($data, true);
	if (!empty($data['access_token'])) {
		// Токен получили, получаем данные пользователя.
		$ch = curl_init('https://login.yandex.ru/info');
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, array('format' => 'json')); 
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: OAuth ' . $data['access_token']));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_HEADER, false);
		$info = curl_exec($ch);
		curl_close($ch);
 
		$info = json_decode($info, true);
		print_r($info);
	}
}

Результат:

Array
(
    [id] => 474865459
    [login] => it-stories
    [client_id] => 8200b1175081452ba9f8aa0b698000a3
    [display_name] => Роман Сергеевич
    [real_name] => Роман Гринько
    [first_name] => Роман
    [last_name] => Гринько
    [sex] => male
    [default_email] => it-stories@yandex.ru
    [emails] => Array
        (
            [0] => it-stories@yandex.ru
        )

    [birthday] => 1995-01-11
    [default_avatar_id] => 59871/yap1e6EbJjl43jATcZjbRzyzLY-1968643369
    [is_avatar_empty] => 
    [psuid] => 1.AAn5CJ.JU4uFswwzfz_goyc5KtMTr.1R1mdmoWm4q8kIhI8wWi3w
)

Подробнее о формате ответа в документации Яндекса.

Фото пользователя можно получить по ссылке, подставив полученный default_avatar_id: https://avatars.yandex.net/get-yapic/default_avatar_id/islands-retina-50

И размер фото, возможные размеры:

islands-small28×28px
islands-3434×34px
islands-middle42×42px
islands-5050×50px
islands-retina-small56×56px
islands-6868×68px
islands-7575×75px
islands-retina-middle84×84px
islands-retina-50100×100px
islands-200200×200px

Если параметр is_avatar_empty = true, то это означает, что у пользователя нет фото и запрос к avatars.yandex.net вернет заглушку.