Closed aaletov closed 6 months ago
OAuth authorization process. Has parameter redirect_uri
which may contain link to our proxy-page e.g. dormyboba.ru/vk_auth?token=<token>
which will send data to auth service and redirect user back to the bot chat
Authorization Code Flow & users.get()
may be used to authenticate user. Associating user id with our secret problem isn't solved yet. How to pass parameters to redirect_uri
?
HTTP request is fully encapsulated in TLS package, therefore we consider query parameters as safe.
Decided to use readirect_uri
OAuth2 parameter and pass token as a URI parameters to pass token
Переоткрываем, чтобы разобрать возможные варианты реализации с опорой на исходники скрипта https://vk.com/js/api/openapi.js?169 используемого для подключения виджета. Методом технической интуиции выяснено, что по адресу https://vk.com/dist/public/api/openapi.js лежит распакованный исходник, не обработанный вебпаком
На строке 454 поле window.VK
инициализируется пустым объектом
if (!window.VK) window.VK = {}
При этом поля объекта window
являются глобально разделяемыми переменными:
Таким образом, дальнейшее обращение к переменной VK
является обращением к полю window.VK
, создаваемым на строке 454
Метод VK.Observer.subscribe()
(L1362-L1373):
subscribe: function(eventName, handler) {
var
subscribers = this._subscribers();
if (typeof handler != 'function') return false;
if (!subscribers[eventName]) {
subscribers[eventName] = [handler];
} else {
subscribers[eventName].push(handler);
}
},
Ф-я VK.Widgets.AllowMessagesFromCommunity
(L2183-L2200):
VK.Widgets.AllowMessagesFromCommunity = function (objId, options, groupId) {
groupId = parseInt(groupId, 10);
if (!groupId || groupId < 0) throw Error('No group id passed');
options = VK.Util.parseOptions(options);
var params = {
height: ({22: 22, 24: 24, 30: 30})[parseInt(options.height, 10) || 24],
key: options.key ? options.key.substr(0, 256) : '',
group_id: groupId
}, rpc;
return VK.Widgets._constructor('widget_allow_messages_from_community.php', objId, options, params, {}, {
startHeight: params.height,
height: params.height
}, function(o, i, r) {
rpc = r;
});
};
Единственное взаимодействие VK.Widget
и VK.Observer
, происходит в конструкторе виджетов (L2764-L2768):
funcs.publish = function() {
var args = Array.prototype.slice.call(arguments);
args.push(widgetId);
VK.Observer.publish.apply(VK.Observer, args);
};
Аргументы данной функции прокидываются методу VK.Observer.publish.apply
Выяснено, что обычный статический хтмл-ник позволяет корректно обрабатывать ивенты, получен proof-of-concept
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Basic Django Project</title>
<script src="https://vk.com/js/api/openapi.js?169" type="text/javascript"></script>
</head>
<body>
<div id="vk_send_message"></div>
<script type="text/javascript">
<!-- TODO use template for group id -->
const searchParams = new URLSearchParams(window.location.search);
const token = searchParams.get("token");
VK.Widgets.AllowMessagesFromCommunity("vk_send_message", {height: 30}, "223616799");
VK.Observer.subscribe("widgets.allowMessagesFromCommunity.allowed", function f(userId) {
console.log(userId);
console.log("allowed");
fetch("/invite/registerUser", {
method: "POST",
body: JSON.stringify({
token: token,
userId: userId,
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
});
});
VK.Observer.subscribe("widgets.allowMessagesFromCommunity.denied", function f(userId) {
console.log(userId);
console.log("denied");
fetch("/invite/registerUser", {
method: "POST",
body: JSON.stringify({
token: token,
userId: userId,
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
});
});
</script>
</body>
</html>
Рабочее объяснение причин ошибки - заголовки, которые неявно ставит django. Решено использовать fastapi ввиду большей простоты полной переработки модуля с виджетом по сравнению с устранением ошибки в существующем коде
Overview
Telegram Bot API have deep linking mechanism which allows to pass additional parameters on bot startup without any user input. Read Vk Bot API docs and find out does it provide simillar functionality or consider ways to pass additional parameters using some proxy-endpoint + redirect
Probably we can pass parameters using Vk App authentication mechanism