Авторизация — что это такое?
Авторизация пользователя является основополагающей функцией на многих сайтах. Типичный пользователь интернета сталкивается с ней регулярно: в социальных сетях, на форумах, на новостных сайтах при оставлении комментариев, на сайтах банков. Как уже ранее говорилось, при регистрации на сайте можно воспользоваться предоставляемыми дополнительными функциями и возможностями.
Тут-то самое интересное и начинается…
Разберем вторую ссылку по частям:Что означает каждый из параметров:
Собственно в redirect_uri содержался адрес фишинг сайта. Так как в параметре display была допущена ошибка (в него шел мусор “?390852”), окно авторизации не выводилось, а сразу шел редирект на фишинг сайт с параметрами: error=invalid_request&error_description=Invalid display passed
Основные плюсы идентификации
Преимущества имеют как владельцы сайта, так и его пользователи. Для владельца преимуществом являются:
Авторизация для приложений, имеющих серверную часть
- Редирект на страницу авторизации
- На странице авторизации у пользователя запрашивается подтверждение выдачи прав
- В случае согласия пользователя, браузер редиректится на URL, указанный при открытии страницы авторизации, с добавлением в GET-параметры специального ключа — authorization code
- Сервер приложения выполняет POST-запрос с полученным authorization code в качестве параметра. В результате этого запроса возвращается access token
Это самый сложный вариант авторизации, но только он позволяет сервису однозначно установить приложение, обращающееся за авторизацией (это происходит при коммуникации между серверами на последнем шаге). Во всех остальных вариантах авторизация происходит полностью на клиенте и по понятным причинам возможна маскировка одного приложения под другое. Это стоит учитывать при внедрении OAuth-аутентификации в API сервисов.
Авторизация полностью клиентских приложений
- Открытие встроенного браузера со страницей авторизации
- У пользователя запрашивается подтверждение выдачи прав
- В случае согласия пользователя, браузер редиректится на страницу-заглушку во фрагменте (после #) URL которой добавляется access token
- Приложение перехватывает редирект и получает access token из адреса страницы
Этот вариант требует поднятия в приложении окна браузера, но не требует серверной части и дополнительного вызова сервер-сервер для обмена
authorization codeaccess token
Буржуазный, через веб-компоненты
Если вы решили пойти по этому пути, то вам потребуется использовать какую-либо стороннюю GUI-библиотеку (или по крайней мере JavaFX), у которой в арсенале есть свой компонент браузера. Над таким бразуером ваша программа будет иметь полную власть, и вы сможете извлечь адрес, на который вас перенаправил ВК, программными средствами. На JavaFX это можно реализовать следующим образом:
Восстановление предыдущей авторизации
Обычно,
access token
имеет ограниченный срок годности. Это может быть полезно, например, если он передается по открытым каналам. Чтобы не заставлять пользователя проходить авторизацию после истечения срока действия
access token
‘а, во всех перечисленных выше вариантах, в дополнение к
access token
‘у может возвращаться еще
refresh token
. По нему можно получить
access token
Для чего нужна регистрация пользователя
Как вы поняли, идентификация помогает опознать визитера сайта, а также наложить ограничения к его возможностям и ресурсам другим юзерам.
Возникает вопрос: авторизация — что это и зачем лимитировать доступ при помощи нее? Ведь было бы намного проще предоставить возможности сайта всем пользователям. Тем более что процедура регистрации порой занимает не так уж и мало времени. Но есть одна весомая причина, по которой владельцы вводят авторизацию.
Данная информация передается добровольно, а также применяется исключительно с целью распознавания остальными посетителями.
Естественно, у регистрации существует множество других задач и функций, однако эти две наиболее важны.
Если у вас активен старый дизайн вконтакте
Заходим в раздел «Мои настройки
», вкладка «Приватность» и напротив самой нижней строчки «Кому в интернете видна моя страница» выставляем значение «Только пользователям ВКонтакте».
Чтобы проверить все ли вы сделали верно, сделайте следующее. Выберите в меню «Моя страница
», затем нажмите на «Выйти».
После этого должно появиться такое сообщение. «Страница доступна только авторизованным пользователям
Как закрыть свою страничку в контакте от поисковиков? (яндекс, гугл и т.п)
В правом верхнем углу нажимаем на аватарку. Выбираем пункт «Настройки
Выбираем вкладку «Приватность
». Пролистываем вниз до блока «Прочее». Напротив строчки «Кому в интернете видна моя страница» выставляем значение «».
Клиентская авторизация
С клиентской авторизацией действительно нет ничего сложного.
Согласно
, достаточно асинхронно загрузить
и, «повесить»
VK.init({appid: YOUR_APP_ID})
на событие
window.vkAsyncInit
, после чего уже можно вызвать функцию
VK.Auth.login(authInfo, YOUR_APP_PERMISSIONS)
, которая и выполнит авторизацию пользователя.
var vk = {
data: {},
api: "//vk.com/js/api/openapi.js",
appID: YOUR_APP_ID,
appPermissions: YOUR_APP_PERMISSIONS,
init: function(){
$.js(vk.api);
window.vkAsyncInit = function(){
VK.init({apiId: vk.appID});
load();
}
function load(){
VK.Auth.login(authInfo, vk.appPermissions);
function authInfo(response){
if(response.session){ // Авторизация успешна
vk.data.user = response.session.user;
vk.getFriends();
}else alert("Авторизоваться не удалось!");
}
}
},
getFriends: function(){
VK.Api.call('friends.get', {fields: ['uid', 'first_name', 'last_name'], order: 'name'}, function(r){
if(r.response){
r = r.response;
var ol = $('#clientApi').add('ol');
for(var i = 0; i < r.length; i){
var li = ol.add('li').html(r[i].first_name ' ' r[i].last_name ' (' r[i].uid ')')
}
}else alert("Не удалось получить список ваших друзей");
})
}
}
$.ready(vk.init);
Во-первых, сразу оговорюсь, что используемые здесь функции
$
— это не
jQuery
. Тем не менее, их назначение может не быть интуитивно понятным, так что я буду рассказывать, что же делает та или иная функция. Их самостоятельная реализация не должна составить особого труда, ровно как и перекладка всего кода на
jQuery
.
Итак,$.ready(function)
— Это обработчик для DOMContentLoaded
;$.js(text)
— асинхронно загружает javascript файл;$(element)
— возвращает обёртку над DOM узлом element
;$(element).add(node)
— создаёт новый дочерний для element
узел node
и возвращает обёртку над ним;$(element).html(string)
— обёртка для element.innerHTML = string
.
По-сути, этот код делает следующее:
По готовности документа загружается API ВКонтакте, и, после его инициализации, вызывается метод
VK.Auth.login()
, который показывает всплывающее окно,
которое успешно «блочится» любой баннерорезкой
, в котором пользователь должен подтвердить своё согласие предоставить данные клиентскому приложению.
Функция
authInfo
вызывается после согласия или несогласия пользователя, и, в случае успешной авторизации, запрашивает список друзей.
Клиентскую часть таким образом можно считать законченной, однако, стоит как-то предупреждать пользователей о возможности блокировки их браузером окна подтверждения.
Минусы oauth 2.0
Во всей этой красоте есть и ложка дегтя, куда без нее?
OAuth 2.0 — развивающийся стандарт. Это значит, что спецификация еще не устоялась и постоянно меняется, иногда довольно заметно. Так, что если вы решили поддержать стандарт прямо сейчас, приготовьтесь к тому, что его поддержку придется подпиливать по мере изменения спецификации. С другой стороны, это также значит, что вы можете поучаствовать в процессе написания стандарта и внести в него свои идеи.
Безопасность OAuth 2.0 во многом основана на SSL. Это сильно упрощает жизнь разработчикам, но требует дополнительных вычислительных ресурсов и администрирования. Это может быть существенным вопросом в высоко нагруженных проектах.
Пишем класс для работы с api
Перед тем, как написать класс, мы определим его логику, которая будет содержать 3 свойства и 3 метода (включая конструктор).
Примеры работы с api vk (вконтакте) на php
Список методов API Вконтакте | Ограниченияи рекомендации
Простая авторизация
На этом этапе – всё довольно рационально. После того как вы подключите класс к файлу, останется получить экземпляр VKAuth, передав ему настройки. Ниже описываем простой обработчик, который отлавливает переменную $_GET и проверяем аутентификацию.
Require_once(«VKAuth.php»); $vk = new VKAuth(array(«client_id» => «ID_приложения», «client_secret» => «защищенный_ключ», «redirect_uri» => «адрес_сайта»)); if(isset($_GET[«code»])){ if($vk->auth($_GET[«code»])){ // Делаем свои дела } }
Далее, чтобы произвести авторизацию, вам нужно будет проверить наличие пользователя у себя в базе данных и, если его нет, то добавить. В противном случае обновить его данные (перед обновлением желательно проверить — изменились ли они). Касательно базы данных обычно добавляют два поля: тип авторизации и id пользователя в социальной сети. Вот так осуществляется аутентификация и авторизация через социальную сеть «ВКонтакте».
В архиве вы найдёте готовый пример работы с классом VKAuth, где выводятся данные пользователя.
Для чего этого необходимо? Для вызова некоторых функций Вконтакте, которые не доступны через API Вконтакте, или из-за существующий ограничений.
Прямая авторизация приложения vk, как сделать?
Здравствуйте!
Есть desktop приложение, которое авторизует пользователя вконтакте. Путём проб и ошибок в оконцовке пришёл к такому варианту авторизации(получение ACCESS_TOKEN)
В этом методе мы проходим по ссылке, которая будет спрашивать, дать ли этому приложению доступ?
Берём со страницы хэши: ip_h, lg_h, to.
Они нужны для отправки POST запроса на авторизацию.
Попутно вытягиваем печеньку “remixlhk”, без которого ВК не хочет даже здороваться.
private void getCookieremixlhk() throws IOException {
URL url = new URL("https://oauth.vk.com/authorize?client_id=id_вашей_группыredirect_uri=https://oauth.vk.com/blank.html&scope=friends,groups&response_type=token&revoke=1");
ArrayList<String> listHeaders = new ArrayList<>();
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
for (Map.Entry<String, List<String>> pair : conn.getHeaderFields().entrySet()) {
listHeaders.addAll(pair.getValue());
}
for (String listi : listHeaders) {
if (listi.contains("remixlhk")) {
remixlhk = listi.split("=", 2)[1].split(";", 2)[0];
}
}
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
while (in.ready()) {
String temp = in.readLine();
if (temp.contains("ip_h"))
ip_h = temp.split("value="", 2)[1].split(""")[0];
if (temp.contains("lg_h"))
lg_h = temp.split("value="", 2)[1].split(""")[0];
if (temp.contains("name="to""))
to = temp.split("value="", 2)[1].split(""")[0];
}
in.close();
}
Дальше мы отправляем POST запрос на авторизацию.
Из страницы ответа берём ссылку на подтверждение доступа приложению…
private void fullAuthorization() throws IOException {
URL url = new URL("https://login.vk.com/?act=login&soft=1");
Map<String, Object> params = new LinkedHashMap<>();
params.put("_origin", "https://oauth.vk.com");
params.put("email", email);
params.put("expire", "0");
params.put("ip_h", ip_h);
params.put("lg_h", lg_h);
params.put("pass", pass);
params.put("to", to);
params.put("Cookie", "remixlhk=" remixlhk);
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setDoOutput(true);
conn.getOutputStream().write(postDataBytes);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
while (in.ready()) {
String temp = in.readLine();
if (temp.contains("grant_access")) {
linkAccept = temp.split("form method="post" action="")[1].split(""", 2)[0];
}
}
}
… и проходим по ней, передав печеньку.
Из URL страницы ответа получаем токен и айди пользователя.
private void acceptAndGetToken() throws IOException {
URL url = new URL(linkAccept);
Map<String, Object> params = new LinkedHashMap<>();
params.put("Cookie", "remixlhk=" remixlhk);
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setDoOutput(true);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String URL = conn.getURL().toString();
ACCESS_TOKEN = URL.split("token=", 2)[1].split("&", 2)[0];
vk_id = Integer.valueOf(URL.split("user_id=", 2)[1]);
}
Ну тут создаем пользователя для обращения к VK API(которое будет использоваться и дальше) и достаём его имя, чтобы поприветствовать.
private void getVkFirstNameCurrentUser() throws IOException, ClientException, ApiException {
actor = new UserActor(vk_id, ACCESS_TOKEN);
vkFirstName = vkApiClient.account().getProfileInfo(actor).execute().getFirstName();
}
Собственно проблема. Даже две.
1. Практически всегда авторизация проходит только со второго раза, ошибка выскакивает при попытке авторизации, то есть при получении ссылки из метода 2(fullAuthorization). Бывает, что проходит с первого раза, бывает только со второго. Третий раз никогда не требуется. Если первый раз не прошло, закрываю ошибку и повторяю попытку авторизации. Всё получается. Есть идеи, в чём может быть проблема?
2. Самая тупая проблема, просто магия. Я, конечно, в магию верю, но может у кого нибудь будет идея, как эта магия работает?
Для GUI использую JavaFX. Есть FXML файл следующего содержания.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.web.WebView?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="260.0" prefWidth="296.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mainpackage.view.login.LoginPageController">
<children>
<ButtonBar layoutX="5.0" layoutY="209.0" prefHeight="40.0" prefWidth="246.0" AnchorPane.bottomAnchor="11.0" AnchorPane.rightAnchor="26.0">
<buttons>
<Button mnemonicParsing="false" onAction="#handleOkButtonClicked" text="OK" />
<Button mnemonicParsing="false" onAction="#handleCancelButtonClicked" text="Cancel" />
<Button mnemonicParsing="false" onAction="#handleNoAuthButtonClicked" text="No Auth" />
</buttons>
</ButtonBar>
<TextField fx:id="loginTextField" layoutX="26.0" layoutY="67.0" prefHeight="25.0" prefWidth="246.0" />
<Label layoutX="28.0" layoutY="42.0" text="Login" />
<Label layoutX="28.0" layoutY="109.0" text="Password" />
<Label layoutX="32.0" layoutY="14.0" prefWidth="153.0" text="Authorization on VK.com" AnchorPane.leftAnchor="70.0" AnchorPane.rightAnchor="70.0" AnchorPane.topAnchor="10.0">
<font>
<Font name="Arial Bold" size="12.0" />
</font>
</Label>
<PasswordField fx:id="passwordTextField" layoutX="26.0" layoutY="135.0" prefHeight="25.0" prefWidth="246.0" />
<WebView fx:id="webViewOnLogin" prefHeight="0.1" prefWidth="0.1" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<Label fx:id="textAfterAuthorization" alignment="CENTER" contentDisplay="CENTER" layoutX="27.0" layoutY="177.0" prefHeight="17.0" prefWidth="246.0" text="Авторизация занимает 5-10 секунд" />
</children>
</AnchorPane>
Обратите внимание на элемент WebView практически в самом конце. Изначально авторизация была путём открывания WebView в приложении, но захотелось сделать прямую авторизацию. Красивше всё таки.
Пока делал, WebView был на месте, после того, как все получилось(авторизация), стал чистить код и удалил WebView. Всё сломалось. Не хочет он логиниться, говорит, пароль неверный.
Убрал все упоминания WebView из кода, остался только в FXML файле. Он больше нигде не используется. Размеры его 0.1 на 0.1. Но без него авторизация не работает совершенно.
Есть идеи, как можно расколдовать принцессу?
Реализация автопостинга записей на стену (wall.post)
1. При регистрации приложения указываем тип платформы «Standalone-приложение»
2. Формируем ссылку и переходим по ней в браузере
client_id — ID вашего приложения, остальные параметры без изменений.
3. После перехода по ссылке и авторизации произойдёт редирект на url, который содержит токен. Этот токен сохраняем.
d5f00aca2251588a1e6d67e401d1e…. — токен
4. Устанавливаем библиотеку vk-php-sdkcomposer require vkcom/vk-php-sdk
5. Применяем метод wall.post для публикации сообщений в группу:
Регистрация на сайте через вконтакте – seolik блог
Мы начинаем цикл статей, в которых расскажем и покажем как сделать для своего сайта очень удобный функционал регистрации и/или авторизации для ваших пользователей на вашем сайте через социальные сети ВКонтакте, Одноклассники, Яндекс, Google и Mail.ru.
В данной статье рассмотрим регистрацию на сайте через социальную сеть ВКонтакте.
Создайте в корне своего сайта 2 папки, например social_login и social_login_callback. В первой будут храниться файлы для использования их в качестве прямых ссылок на инициализацию аутентификации в социальной сети, а во второй обработчики ответов от социальных сетей
Создайте новое приложение в социальной сети ВКонтакте
В открывшейся форме введите название приложения, выберите тип “Веб-сайт”, укажите адреса сайта и базовый домен сайта.
После нажатия на кнопку “Подключить сайт”, вам придётся ввести проверочный код, который придёт по смс. После ввода кода, перейдите в раздел Настройки.
Из данной формы нам понадобятся такие данные, как `ID приложения`, `Защищённый ключ`, `Доверенный redirect URI:`.
Доверенный redirect URI: вам нужно прописать полный путь к файлу обработчика ответа от социальной сети, в нашем случае: https://vhod-v-lichnyj-kabinet.ru/social_login_callback/vk.php
Обратите внимание, что такие данные как `Защищённый ключ` в примере у нас изменены на фиктивные, так как публикация реальных данных поля `Защищённый ключ` может повлечь за собой удаление приложения или даже вашего аккаунта в социальной сети.
Создаем файл vk.php в папке social_login (пример можно будет скачать в конце статьи) и записываем в него код:
$client_id = 'XXXXXXXX'; // ID приложения
$client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxx'; // Защищённый ключ
$redirect_uri = 'https://site.ru/social_login_callback/vk.php'; // куда ответ
$url = 'https://oauth.vk.com/authorize';
$params = array(
'client_id' => $client_id,
'scope' => 'email',
'redirect_uri' => $redirect_uri,
'response_type' => 'code'
);
header('Location: '. $url . '?' . urldecode(http_build_query($params)) ); exit();
Теперь у нас готова ссылка при переходе по которой пользователь инициирует авторизацию через социальную сеть, а именно ссылка имеет вид https://site.ru/social_login/vk.php
Для того, чтобы получить ответ от социальной сети и email юзера создадим файл vk.php, но теперь в папке social_login_callback и запишем в него следующий код:
$client_id = 'XXXXXXX'; // ID приложения
$client_secret = 'xxxxxxxxxxxxxxxxxxxx'; // Защищённый ключ
$redirect_uri = 'https://site.ru/social_login_callback/vk.php'; // куда ответ
if (isset($_GET['code'])) {
$result = false;
$params = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'code' => $_GET['code'],
'redirect_uri' => $redirect_uri,
);
$token = json_decode(file_get_contents('https://oauth.vk.com/access_token' . '?' . urldecode(http_build_query($params))), true);
if (isset($token['access_token'])) {
$params = array(
'uids' => $token['user_id'],
'fields' => 'uid,first_name,last_name,screen_name,sex,bdate,photo_big',
'access_token' => $token['access_token'],
);
$userInfo = json_decode(file_get_contents('https://api.vk.com/method/users.get' . '?' . urldecode(http_build_query($params))), true);
$email = $token['email']; // почта юзера
if (isset($userInfo['response'][0]['uid'])) {
$userInfo = $userInfo['response'][0];
$result = true;
}
}
if ($result) {
echo "Социальный ID пользователя: " . $userInfo['uid'];
echo "Имя пользователя: " . $userInfo['first_name'];
echo "Фамилия пользователя: " . $userInfo['last_name'];
echo "Emai пользователя: " .$email;
echo "Ссылка на профиль пользователя: " . $userInfo['screen_name'];
echo "Пол пользователя: " . $userInfo['sex'];
echo "День Рождения: " . $userInfo['bdate'];
echo "URL к фото: ".$userInfo['photo_big'];
}
}
Т.е теперь при успешном ответе от социальной сети, если юзер разрешил доступ к своей информации и у него указан email в настройках профиля, в ответе вы получите данные о нем, в том числе и его email. Ну а дальше дело за вами, создавайте для него аккаунт у вас на сайте на основе его email.
Регистрация приложения
Скорее всего Вы уже зарегистрированы в соц. сети ВКонтакте, если нет, то Вам придется это сделать. Указывать номер телефона при регистрации обязательно. Переживать не стоит — никакой смс-рассылки от этих сервисов не приходит.Далее необходимо создать приложение. (Скриншоты были сделаны в апреле 2022, с той поры интерфейс мог измениться)
После смс-подтверждения создания приложения оно, как можно догадаться, создаётся и Вы попадаете на страницу её редактирования. Всю информацию и иконки желателно добавить, но больше всего нас там интересуют id приложения и защищённый ключ— это и есть идентификационные данные нашего сайта:
Приложения ВКонтакте поддерживают работу с несколькими доменами, так что можно создать одно приложение сразу для всех Ваших сайтов.
Серверная авторизация
Серверная авторизация гораздо веселее. Механизм серверной авторизации для доступа к ВКонтакте API с стороннего сайта создан на базе протокола OAuth 2.0.
Процесс авторизации происходит следующим образом:
- Необходимо в браузере пользователя показать страницу, где он разрешит приложению доступ к своим данным;
- После успешной авторизации приложения браузер пользователя будет перенаправлен по адресу REDIRECT_URI, указанному при открытии диалога авторизации. При этом в GET-параметре будет передан код для получения ключа доступа;
- Необходимо выполнить запрос с передачей кода и секретных данных приложения на специальный адрес, в ответ мы получим ключ доступа access_token, необходимый нам для совершения запросов к API.
К сожалению, второй пункт, а именно, перенаправление браузера, срабатывает далеко не всегда, точнее, не срабатывает нигде, кроме ИЕ, в тот самый первый раз, когда пользователь впервые разрешает приложению доступ к своим данным. И как только не извращаются разработчики, лишь бы получить заветный код.
К тому же, открытие дополнительного окна опять-таки связано с опасностью, что оно будет заблокировано.
К счастью, если мы знаем ссылку, по которой нужно открыть окно, есть много хороших способов открыть его так, чтобы оно не было заблокировано. Например, старый добрый тег iframe всё ещё в строю стандарта HTML, и он как нельзя лучше подходит для нашей задачи.
Во-первых, раз мы знаем адрес, то мы можем и открыть фрейм и показать пользователю ссылку, где можно всё проделать вручню.
Во-вторых, если-таки происходит редирект, и в фрейме открывается страница с нашего домена, то мы можем получить из фрейма доступ к главному окну и автоматически запустить функцию закрытия фрейма. При этом на сервере уже будет access_token, который мы сохраним в сессии и выполняя с главного окна запросы к серверу сможем получать ответы. Перезагрузки страницы при этом не произойдёт, что полностью решает нашу задачу.
В-третьих, если перенаправления не произошло, и пользователь вручную открыл страницу подтверждения доступа приложения, то там уже точно происходит редирект, на страницу с нашего домена, которая будет открыта не во фрейме, а вместо главной. К сожалению, это и есть перезагрузка, но это меньшая жертва, чем могло бы быть. С этой страницы можно отправить пользователя снова на главную, во второй раз авторизация пройдёт уже без перезагрузок.
Реализацию класса доступа к VK API по OAuth на PHP можно легко найти на гитхабе, что я и сделал (PHP >= 5.4).(Совершенно случайно оказалось, что этот класс, скорее всего, написан хабрапользователем vladkens, за что ему огромное спасибо)
Теперь перейдём к самому интересному.
<?php
require_once('vk.php');
session_start();
function getPostStr($data, $default = false){ // возврачает строку - значение $_POST[$data]
if(!isset($_POST[$data])) return $default;
$data = $_POST[$data];
$data = htmlspecialchars(strip_tags(trim($data)));
return ($data != "" ? $data : $default);
}
function error($code, $text, $params = Array()){
$result = Array('error' => Array('code' => $code, 'message' => $text));
if(count($params) > 0) foreach($params as $key => $value) $result['error'][$key] = $value;
die(json_encode($result));
}
$vkConf = Array(
'appID' => YOUR_APP_ID,
'apiSecret' => YOUR_API_SECRET,
'callbackUrl' => YOUR_DOMAIN . '/auth.php',
'apiSettings' => YOUR_APP_PERMISSIONS
);
$vk = (isset($_SESSION['accessToken']))
? new VK($vkConf['appID'], $vkConf['apiSecret'], $_SESSION['accessToken']) : null;
function userIn($vk, $vkConf){ // Авторизация пользователя
unset($_SESSION['accessToken']);
$vk = new VK($vkConf['appID'], $vkConf['apiSecret']);
$authorizeUrl = $vk -> getAuthorizeURL($vkConf['apiSettings'], $vkConf['callbackUrl']);
error(-1, "Необходима авторизация ВКонтакте!", Array('url' => $authorizeUrl));
}
function getFriends($fields, $order, $vk){ // Получение списка друзей пользователя
$userFriends = $vk -> api('friends.get', array('fields' => $fields, 'order' => $order));
$result = Array();
foreach($userFriends['response'] as $key => $value){
$result[] = Array('firstName' => $value['first_name'], 'lastName' => $value['last_name'], 'uid' => $value['uid']);
}
echo json_encode($result);
}
$method = strtolower($api -> getStr("method"));
switch($method){
case "user.in" : userIn($vk, $vkConf); break;
case "friends.get" : getFriends(getPostStr("fields"), getPostStr("order"), $vk); break;
default: Api::error(0, "Неверный запрос к Api");
}
?>
Запросы на эту страницу мы будем посылать методом POST, где параметр
method
содержит название метода, который мы хотим выполнить на сервере.
Формирование ссылки для авторизации пользователя и получение токена (access token)
Подробная документация.
Формируем ссылку и выводим её на экран:
// Параметры приложения
$clientId = ‘6483919’; // ID приложения
$clientSecret = ‘yeHH2R4AnqVgrHwo3r893’; // Защищённый ключ
$redirectUri = ‘http://localhost/_blog/tests/vk-api/oauth.php’; // Адрес, на который будет переадресован пользователь после прохождения авторизации
// Формируем ссылку для авторизации
$params = array(
‘client_id’ => $clientId,
‘redirect_uri’ => $redirectUri,
‘response_type’ => ‘code’,
‘v’ => ‘5.74’, // (обязательный параметр) версия API, которую Вы используете https://vk.com/dev/versions
// Права доступа приложения https://vk.com/dev/permissions
// Если указать “offline”, полученный access_token будет “вечным” (токен умрёт, если пользователь сменит свой пароль или удалит приложение).
// Если не указать “offline”, то полученный токен будет жить 12 часов.
‘scope’ => ‘photos,offline’,
);
// Выводим на экран ссылку для открытия окна диалога авторизации
echo ‘<a href=”http://oauth.vk.com/authorize?’ . http_build_query( $params ) . ‘”>Авторизация через ВКонтакте</a>’;
session_start();// Токен будем хранить в сессии // Параметры приложения $clientId =‘6483919’;// ID приложения $clientSecret=‘yeHH2R4AnqVgrHwo3r893’;// Защищённый ключ $redirectUri =‘http://localhost/_blog/tests/vk-api/oauth.php’;// Адрес, на который будет переадресован пользователь после прохождения авторизации // Формируем ссылку для авторизации $params=array( ‘client_id’ =>$clientId, ‘redirect_uri’ =>$redirectUri, ‘response_type’=>‘code’, ‘v’ =>‘5.74’,// (обязательный параметр) версия API, которую Вы используете https://vk.com/dev/versions // Права доступа приложения https://vk.com/dev/permissions // Если указать “offline”, полученный access_token будет “вечным” (токен умрёт, если пользователь сменит свой пароль или удалит приложение). // Если не указать “offline”, то полученный токен будет жить 12 часов. ‘scope’ =>‘photos,offline’, ); // Выводим на экран ссылку для открытия окна диалога авторизации echo‘<a href=”http://oauth.vk.com/authorize?’.http_build_query($params).‘”>Авторизация через ВКонтакте</a>’; |
После нажатия на «Авторизация через Вконтакте» будет открыто окно диалога авторизации и пользователю будет предложено авторизовать приложение, разрешив доступ к необходимым настройкам, запрошенным при помощи параметра scope.После успешной авторизации приложения браузер пользователя будет перенаправлен по адресу redirect_uri, указанному при открытии диалога авторизации.
Чем отличаются openid и oauth
Не смотря на то, что объяснений на эту тему уже было много, она по-прежнему вызывает некоторое непонимание.
Шаг второй. формирование специальной ссылки
Далее вам нужно направить пользователя по специально сформированному адресу (её упоминания выделены жирным цветом в первом разделе статьи), где он подтвердит, что хочет разрешить вашему приложению выполнять какие-то действия со своим аккаунтом. Как же формируется эта ссылка?
Этот процесс подробно описан в документации . Однако, если вы обратились к этой статье, я предполагаю, что вам не хватило информации в документации, и поэтому перескажу всё своими словами. Ссылка имеет следующий вид: хост?параметры. Параметры имеют вид нескольких пар вида ключ=значение разделённых символами & .
Заключение
Таким образом, мы научились получать access token ВКонтакте, с помощью которого можно вызывать методы API. Если эта статья вызовет у сообщества интерес, в следующей статье я опишу, как вызывать те или иные API-методы с помощью токена, как проверять токен на валидность (метод secure.checkToken() , конечно), и напишу какое-нибудь демонстрационное приложение, например, для сохранения всей музыки из плейлиста на компьютер.