Я бы хотел предложить свое решение:
Защиту данных можно разделить на следующие аспекты:
1. Подтверждение информации о пользователе.
Чтобы получить достоверные подписанные данные о пользователе, необходимо использовать первый запрос к API в настройках приложения.
method=getProfiles&uids={viewer_id}&format=json&v=2.0Тем самым мы получаем несколько параметров, один из которых нужный нам - viewer_id, а также сигнатуру данных (auth_key), подписанных секретным ключом, который гарантирует нам верность данных.
Т.е. на следующих этапах мы можем использовать информацию о пользователе, не боясь что данные были подменены.
2. Передача данных от пользователя к приложению
Чтобы скрыть секретный ключ и при этом иметь возможность передать данные на сервер придется использовать промежуточное звено - наш ajax обработчик.
Клиентский JavaScript:
function secureSend(_data, _callback) { $.ajax({ type: "POST", url: "ajax.php", data: (_data), dataType: "json", success: function(data) { if(data.error != undefined) { error(data.error); return false; } else { _callback(data.response); } } }); }На сервере же расположить скрипт обрабатывающий только обращения к API, которые пересылают данные от пользователя к серверу. Разрешить можно все действия, т.к. пользователя мы проверили на предыдущем этапе и уже тут он волен сколько угодно раз пересылать свои голоса к приложению :)
ajax.php, серверный скрипт
$vk_allow_methods = array("secure.withdrawVotes", "secure.getBalance"); $q = $_POST; $d = ""; if(in_array($q['method'], $vk_allow_methods)) { $d = vkSend($q['method']); } function vkSend($method) { $server = "http://api.vkontakte.ru/api.php?"; $key = "000"; $aid = 1; $qr = array(); $qr[] = 'method='.$method; $qr[] = 'api_id='.$aid; $qr[] = 'v=2.0'; $qr[] = 'format=JSON'; $qr[] = 'timestamp='.time(); $qr[] = 'random='.rand(1, 999999); $qr[] = 'test_mode=1'; sort($qr); $url4sign = implode("", $qr).$key; $sign = md5($url4sign); $url = implode("&", $qr)."&sig=".$sign; return file_get_contents($server.$url); } echo $d;
3. Передача данных от приложения к пользователю.
Такие события не должны ни в коем случае инициироваться клиентским кодом. Если необходимо перевести голоса со счета приложения на счет пользователя, то лучше воспользоваться запароленым скриптом, вызывающимся по cron или вручную администратором.
А как сделать кнопку, что бы она списывала голос из приложения, а затем переходила на другую страничку iframe приложения? Помогите пожалуйста.
ОтветитьУдалитьЭмм, а перезапись document.location.href в колбэке запроса не прокатывает?
ОтветитьУдалитьfunction secureSend(_data, _callback) {
$.ajax({
type: "POST",
url: "ajax.php",
data: (_data),
dataType: "json",
success: function(data) {
if(data.error != undefined) {
return false;
} else {
document.location.href="ok.html";
}
}
});
}
Работает кнопка только на первой страничке(((
ОтветитьУдалитьна другой, где нужно пишет invalid user id
думаю, потому что запрос к api на других страничках не работает.
первый запрос к API в настройках приложения.
method=getProfiles&uids={viewer_id}&format=json&v=2.0
Ко всем ссылкам автоматически добавлять параметры из $_GET (auth_key, viewer_id, api_url).
ОтветитьУдалитьПервый раз данные будут получены от Вконтакте, далее они будут передаваться по ссылке.
с главной все работает, а с других страничек не работает. в чем может быть проблемма?
ОтветитьУдалитьЕще раз:
ОтветитьУдалить<?
//index.php
function getUriParam() {
return 'api_url='.$_GET['api_url'].'&api_id='.$_GET['api_id'].'&viewer_id='.$_GET['viewer_id'].'&auth_key='.$_GET['auth_key'];
}
echo '<a href="link.php?do=something&'.getUriParam().'">Другая страница</a>';
?>
<?
//link.php?do=something&api_url=...&api_id=...&viewer_id=...&auth_key=...
print_r($_GET);
?>
Т.е. другой странице эти параметры нужно передать как часть ссылки, чтобы можно было их использовать повторно.
ОтветитьУдалитьУ меня ситуация немного другая. Как файл (картинка) загружается, автоматически переходит на другую страничку.
ОтветитьУдалитьВыглядит это так:
function compf() {
window.location.href="crop.php";
}
1. Разбейте location.href на составляющие:
ОтветитьУдалить- самостоятельно, используя arr.split("&")
- использую функционал вконтакте:
VK.init(function() {
VK.loadParams(document.location.href);
}, function(){}
);
2. Добавьте разбитые параметры к location:
window.location.href="crop.php?viewer="+VK.params.viewer_id+"...";
Алексей, а как передаются в приложение данные с урла.
ОтветитьУдалитьПользователь запрашивает страницу:
vkontakte.ru/appXXXXXXX#comment/&f_id=15
а мне в приложение передается строка:
mysite.ru/vk/comment/&f_id=15.
Как получить этот кусок:
comment/&f_id=15
Где физический находится приложение? mysite.ru/vk/ ?
ОтветитьУдалитьЕсли так, то нужно использовать mod_rewrite и в скрипте парсить серверную переменную $_SERVER['QUERY_STRING'].
Ну или переделать, если не охота использовать мод реврайт, чтобы параметры передавались в виде ?act=comment&f_id=15
Эм... глупый вопрос наверно задам. Но я новичёк во всём этом. Сделал как написано, скрипт на сервере, код джава на главной странице и в настройках первый запрос стоит... А что дальше? Как например передать запрос теперь на получение счёта пользователя в приложении? Очень прошу, подскажите.
ОтветитьУдалитьАндрей, обратитесь к документации
ОтветитьУдалитьhttp://vkontakte.ru/pages.php?o=-1&p=%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5+%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2+API
или к официальной группе iframe приложений, там вам помогут
http://vkontakte.ru/club15957347
Здравствуйте, возможно не лучшее место чтобы поднять вопрос, но гугл не помог, а тут вроде как раз подходящая тема.
ОтветитьУдалитьИспользую аналогичный jquery-ajax запрос, и вроде бы все ничего, но в опере вылезает ошибка. Что то в духе того что не хватает прав. Как я понял свзано это с тем что она запрещает кросс-доменные запросы. Без iframe, в отдельном окне, приложение работает везде, в том числе и в Опере.
На сколько я понял какая то хитрость связанная с тем что Опера считает что запрос из вконтактовского iframe идет на другой домен. Может быть есть какая то информация на этот счет и как все-таки заставить его работать?
Когда делал приложение, то проверял и в Опере. Все работало.
ОтветитьУдалитьВы надеюсь используете jsonp запросы?
Также советую прочитать 7 пункт на этой странице http://vkontakte.ru/page-15957347_10972154, возможно в этом проблема.
Чтобы получить достоверные подписанные данные о пользователе, необходимо использовать первый запрос к API в настройках приложения.
ОтветитьУдалитьДостоверным здесь будет только viewer_id, api_id - больше ничего.
А зачем это пром. звено, если можно все словить в скрипте на сервере, через GET, а далее проверить ?