- PVSM.RU - https://www.pvsm.ru -

Модуль авторизации для сайта, использующий Wargaming.net Public API

С момента выхода WG P API в бета тест, самым популярным вопросом стал «как сделать авторизацию на сайте».
Так уж сложилось — человек существо ленивое.
Дабы упростить жизнь другим участникам Wargaming Developer Partner Program, хочу поделиться свои опытом создания модуля авторизации для сайта.

Варианта два.
1. Использовать OpenID
Логику процесса авторизации [1] wargaming уже описал, статей об OpenID на хабре так же достаточно.
2. Использование методов API для создания модуля авторизации.
Я не буду описывать плагины для всех популярных CMS — опишу лишь общую схему и приведу пример кода.

Теория

Для аутентификации пользователей, на данный момент, у WG API, есть три метода:
auth/login [2] — метод используется для аутентификации пользователя — получения access_token.
auth/prolongate [3] — с помощью этого метода можно продлить access_token без участия пользователя
auth/logout [4] — метод для уничтожения access_token

access_token используется для получения приватной информации об аккаунте игрока — информация о технике, которая есть в ангаре, идентификаторы аккаунтов друзей игрока и прочее.

Для получения access_token, как уже сказано выше, используется метод auth/login, который отправляет информацию о статусе авторизации по адресу указанному в параметре redirect_uri

Один из разработчиков WG сообщил:

Принято решение расширить возможности метода auth/login и будет введено разделение (при успешно введенных сведениях):
1) На один URL будет сделана переадресация пользователя;
2) На второй будет отправлены сведения по авторизации (методом POST или GET).

Вернемся к теории.

Алгоритм работы

Генерация ссылки для перенаправления пользователя

Прежде всего, нужно обратиться к методу auth/login с просьбой сгенерировать URL для дальнейшего редиректа пользователя.
Для этого шлем запрос к
https://api.worldoftanks.ru/wot/auth/login/?application_id=<application_id>&redirect_uri=<redirect_uri>&nofollow=1
, где <application_id> — application_id приложения, для получения которого нужно зарегистрироваться в кабинете разработчика [5];
<redirect_uri> — URL скрипта обработчика;
Значение параметра nofollow=1, что бы метод возвратил URL в теле ответа вместо редиректа.

Наш auth.php будет выполнять сразу две задачи: генерировать ссылку и производить редирект по ней, или же производить авторизацию, если пользователь вернулся после редиректа.

Перенаправление пользователя на сайт WG

В примере, скрипт сам делает перенаправление пользователя после генерации ссылки.
Изменив пару строк кода, можно замутить это с помощью javascript, дабы написать «Загрузка...» (или вставить loader.gif) после клика по кнопке «Войти» — это всегда выглядит красиво.
В то время, пока пользователь восхищается надписью (ну или картинкой), js отправит запрос к скрипту, тот отправит запрос к api, api ответит скрипту, скрипт вернет ссылку, и наконец таки js перенаправит пользователя по ней.
Напрямую отправлять запрос к API js-ом нельзя, поскольку правилами WG DPP, запрещено разглашать application_id приложения.

Возврат пользователя

После того как игрок авторизируется на сайте WG и разрешит нашему сайту просматривать его детальную статистику он будет перенаправлен на
<redirect_uri>?&status=ok&access_token=<access_token>&nickname=<_nickname>&account_id=<account_id>&expires_at=<expires_at>
Если не произойдет никаких ошибок…
Таким образом наш скрипт получит данные:
status access_token nickname account_id expires_at
Но пока этим данным нельзя доверять!

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

Если мы планируем делать авторизацию, то должны быть уверенны, что полученные данные правдивы и переданы именно с сайта WG, а не прописаны вручную.
Вот именно из-за этого момента и будет переделана работа метода — на данный момент, мы не можем точно знать, пришел ли игрок, с этими параметрами, с сайта wargaming или сам набрал их в адресной строке.
$_SERVER['HTTP_REFERER'] не дает полной гарантии.

Для того, что бы проверить правдивость данных мы воспользуемся методом auth/prolongate
Это один из вариантов. Кроме пролонга мы можем так же сделать запрос на account/info с полученным токеном — если удастся получить приватные данные, значит все ок.
Воспользовавшись им мы сможем проверить, действительный ли access_token был передан, и кому (account_id) он принадлежит.
Если все в порядке, мы запишем нужные данные в БД, установим пользователю куки — сделаем всё то, что нужно делать при стандартной авторизации с вводом логина/пароля.

Практика

<?
define('URL','http://example.com/WGDPPAuth.php');//адрес по которому доступен данный скрипт
define('APPLICATION_ID','demo');//application_id приложения
if(empty($_GET['status'])){//генерируем ссылку и перенаправяем пользователя
	$context = stream_context_create(
		array('http' =>
			array(
				'method'  => 'POST',
				'header'  => 'Content-type: application/x-www-form-urlencoded',
				'content' => http_build_query(
					array(
						'nofollow' => 1,
						'expires_at' => 300,
						'redirect_uri' => URL,
						'application_id' => APPLICATION_ID
					)
				)
			)
		)
	);
	$data=json_decode(@file_get_contents('https://api.worldoftanks.ru/wot/auth/login/', false, $context),true);
	if($data['status']=='ok'){
		header ('Location: '.$data['data']['location']);
		exit();
	}else{
		exit('Не удалось получить ссылку для перенаправления.');
	}
}elseif(isset($_GET['status']) && isset($_GET['access_token']) && isset($_GET['nickname']) && isset($_GET['account_id']) && isset($_GET['expires_at'])){//если пользователь попал на страницу с параметрами, которые устанавливает метод auth/login
	if($_GET['status']!="ok"){
		$error_code=500;
		if(preg_match('/^[0-9]+$/u', $_GET['code'])){
			$error_code=$_GET['code'];
		}
		exit("Ошибка авторизации. Код ошибки: $error_code");
	}elseif($_GET[expires_at]<time()){
		exit("Ошибка авторизации. Срок действия access_token истек.");
	}else{
		$context = stream_context_create(
			array('http' =>
				array(
					'method'  => 'POST',
					'header'  => 'Content-type: application/x-www-form-urlencoded',
					'content' => http_build_query(
						array(
							'expires_at' => 14*24*60*60,
							'access_token' => $_GET['access_token'],
							'application_id' => APPLICATION_ID
						)
					)
				)
			)
		);
		$data=json_decode(@file_get_contents('https://api.worldoftanks.ru/wot/auth/prolongate/', false, $context),true);//подтверждаем правдивость полученных параметров
		if($data['status']=="ok"){
			$access_token=$data[data][access_token];
			$expires_at=$data[data][expires_at];
			$account_id=$data[data][account_id];
			//здесь вам нужно установить пользователю куки, записать его токен в БД, сделать все то, что сочтете нужным.
			exit('Это пользователь с id <b>'.$account_id.'</b><br />Токен <b>'.$access_token.'</b>, он подтвержден и действует до <b>'.date("d.m.Y H:i:s",$expires_at).'</b>');
		}else{
			exit('access_token не подтвержден');
		}
	}
}else{
	$error_code=500;
	if(preg_match('/^[0-9]+$/u', $_GET['code'])){
		$error_code=$_GET['code'];
	}
	exit("Произошла ошибка. Код ошибки: $error_code");
}
?>

DEMO [6]

Автор: Samber

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/api/67985

Ссылки в тексте:

[1] Логику процесса авторизации: https://ru.wargaming.net/support/Knowledgebase/Article/View/710/25/autentifikcija-openid

[2] auth/login: https://ru.wargaming.net/developers/api_reference/wot/auth/login/

[3] auth/prolongate: https://ru.wargaming.net/developers/api_reference/wot/auth/prolongate/

[4] auth/logout: https://ru.wargaming.net/developers/api_reference/wot/auth/logout/

[5] кабинете разработчика: http://ru.wargaming.net/developers/

[6] DEMO: http://project357.hol.es/WGDPPAuth.php

[7] Источник: http://habrahabr.ru/post/233957/