Авторизация в VK для людей
Здравствуй, дорогой читатель. Если тебе хотя бы однажды доводилось работать с API Вконтакте и при этом писать все на python , вероятно, авторизация приложения заставила тебя сделать несколько приседаний, после которых ног либо не чувствуешь и падаешь в обморок, либо вкачиваешь квадрицепс и все же пробиваешь API, как Ван Дамм.
По какой-то причине этот, казалось бы, самый непримечательный этап поначалу отнимает огромное количество сил и времени. Моя задача: помочь читателям Хабра избежать травм ног.
Далее я предлагаю рассмотреть небольшую библиотеку, позволяющую в одну строчку авторизовать свое приложение для конкретного пользователя и получить access_token . В конце статьи представлена ссылка на github-репозиторий этой библиотеки с quickstart’ом в README -файле.
Задача
Хотим небольшой модуль, который позволяет провести авторизацию красиво, универсально и максимально надежно, а использовать который очень просто.
Стоит сказать, что данное решение является усовершенствованием и обобщением варианта, предложенного в этой статье.
Итак, используем python3.5 , библиотеку для html запросов requests и getpass для скрытого ввода пароля.
Наша задача: несколько раз обратиться по верному адресу, каждый раз парсить , отправлять ответ и наконец получить желанный access_token .
Реализация
Начнем с создания класса. При инициализации будем требовать список «разрешений», к которым приложение хочет получить доступ, id этого приложения и версию API VK. Плюсом добавим несколько необязательных параметров, значение каждого из которых прояснится далее.
Метод __init__
class VKAuth(object): def __init__(self, permissions, app_id, api_v, email=None, pswd=None, two_factor_auth=False, security_code=None, auto_access=True): """ Args: permissions: list of Strings with permissions to get from API app_id: (String) vk app id that one can get from vk.com api_v: (String) vk API version """ self.session = requests.Session() self.form_parser = FormParser() self.user_id = None self.access_token = None self.response = None self.permissions = permissions self.api_v = api_v self.app_id = app_id self.two_factor_auth= two_factor_auth self.security_code = security_code self.email = email self.pswd = pswd self.auto_access = auto_access if security_code != None and two_factor_auth == False: raise RuntimeError('Security code provided for non-two-factor authorization')
Как было сказано в уже упомянутой статье, нам необходимо искусно ворочать cookie и redirect’ы. Все это за нас делает библиотека requests с объектом класса Session. Заведем и себе такой в поле self.session . Для парсинга html документа используется стандартный класс HTMLParser из модуля html.parser . Для парсера тоже написан класс ( FormParser ), разбирать который большого смысла нет, так как он почти полностью повторяет таковой из упомянутой статьи. Существенное отличие лишь в том, что использованный здесь позволяет изящно отклонить авторизацию приложения на последнем шаге, если вы вдруг передумали.
Поля user_id и access_token будут заполнены после успешной авторизации, response хранит в себе результат последнего html запроса.
Пользователю библиотеки предоставим один-единственный метод – authorize , который совершает 3 шага:
- запрос на авторизацию приложения
- авторизация пользователя
2.1 введение кода-ключа в случае двух-факторной авторизации - подтверждение разрешения на использование permissions
Пройдемся по каждому шагу.
Шаг 1. Запрос на авторизацию приложения
Аккуратно составляем url запроса (про параметры можно прочитать здесь), отправляем запрос и парсим полученный html.
Метод authorize для Шага 1
def authorize(self): api_auth_url = 'https://oauth.vk.com/authorize' app_id = self.app_id permissions = self.permissions redirect_uri = 'https://oauth.vk.com/blank.html' display = 'wap' api_version = self.api_v auth_url_template = '?client_id=&scope=&redirect_uri=&display=&v=&response_type=token' auth_url = auth_url_template.format(api_auth_url, app_id, ','.join(permissions), redirect_uri, display, api_version) self.response = self.session.get(auth_url) # look for element in response html and parse it if not self._parse_form(): raise RuntimeError('No element found. Please, check url address')
Шаг 2. Авторизация пользователя
Реализованы методы _log_in() и _two_fact_auth() для [не]успешной авторизации пользователя в вк, если он не авторизован (а он точно не авторизован). Оба метода используют ранее определенные поля email , pswd , two_factor_auth и security_code . Если какое-то из полей не было подано аргументом при инициализации объекта класса VKAuth , их попросят ввести в консоли, а случае неудачи попросят ввести заново. Двух-факторная авторизация опциональна и по умолчанию отключена, и наш модуль уведомляет пользователя о ее присутствии ошибкой.
Метод authorize для Шага 2 (продолжение Шага 1)
#look for element in response html and parse it if not self._parse_form(): raise RuntimeError('No element found. Please, check url address') else: # try to log in with email and password (stored or expected to be entered) while not self._log_in(): pass; # handling two-factor authentication # expecting a security code to enter here if self.two_factor_auth: self._two_fact_auth()
Метод _log_in для Шага 2
def _log_in(self): if self.email == None: self.email = '' while self.email.strip() == '': self.email = input('Enter an email to log in: ') if self.pswd == None: self.pswd = '' while self.pswd.strip() == '': self.pswd = getpass.getpass('Enter the password: ') self._submit_form() if not self._parse_form(): raise RuntimeError('No element found. Please, check url address') # if wrong email or password if 'pass' in self.form_parser.params: print('Wrong email or password') self.email = None self.pswd = None return False elif 'code' in self.form_parser.params and not self.two_factor_auth: raise RuntimeError('Two-factor authentication expected from VK.\nChange `two_factor_auth` to `True` and provide a security code.') else: return True
Метод _two_fact_auth для Шага 2
def _two_fact_auth(self): prefix = 'https://m.vk.com' if prefix not in self.form_parser.url: self.form_parser.url = prefix + self.form_parser.url if self.security_code == None: self.security_code = input('Enter security code for two-factor authentication: ') self._submit_form() if not self._parse_form(): raise RuntimeError('No element found. Please, check url address')
Шаг 3. Подтверждение permissions и получение access_token
Самое сложное позади. Теперь дело за малым. Используем наше усовершенствование парсера формы, чтоб найти в только что поступившем к нам html документе кнопку с надписью «Allow» и вытащить из нее url подтверждения авторизации. Рядом находится кнопка с отказом – сохраним и ее url. Поле auto_access по умолчанию находится в состоянии True , так что это подтверждение ни чуть не должно осложнить нам жизнь.
Наконец, сохраним полученные access_token и user_id из url, который был передан после подтверждения авторизации.
Теперь можно весело пользоваться VK API.
Метод authorize для Шага 3
# allow vk to use this app and access self.permissions self._allow_access() # now get access_token and user_id self._get_params()
Метод _allow_access для Шага 3
def _allow_access(self): parser = self.form_parser if 'submit_allow_access' in parser.params and 'grant_access' in parser.url: if not self.auto_access: answer = '' msg = 'Application needs access to the following details in your profile:\n' + \ str(self.permissions) + '\n' + \ 'Allow it to use them? (yes or no)' attempts = 5 while answer not in ['yes', 'no'] and attempts > 0: answer = input(msg).lower().strip() attempts-=1 if answer == 'no' or attempts == 0: self.form_parser.url = self.form_parser.denial_url print('Access denied') self._submit_form(<>)
Метод _get_params для Шага 3
def _get_params(self): try: params = self.response.url.split('#')[1].split('&') self.access_token = params[0].split('=')[1] self.user_id = params[2].split('=')[1] except IndexError(e): print(e) print('Coudln\'t fetch token')
github: VKAuth
Оставляйте комментарии и отзывы здесь и на github. Удачи на полях сражений, и берегите ноги.
VK ID — это единый аккаунт для входа в продукты VK, на сайты и в приложения партнеров
Войти в сервис с VK ID можно одним из удобных способов. Например, с помощью кода из SMS или с OnePass. Выбирайте подходящий именно вам.
Автозаполнение данных
Информацию о себе достаточно ввести один раз в едином личном кабинете VK D — и можно входить с её помощью на сайты и в приложения. Сервисы получают только необходимые для регистрации данные.
Безопасность
VK ID обеспечивает конфиденциальность данных, а для дополнительной защиты можно настроить двухфакторную аутентификацию и отслеживать историю активности.
Комфортная среда
VK ID сделает ваше общение более открытым и безопасным — благодаря подтверждению профиля. Серая галочка подскажет, что перед вами аккаунт реального человека. Подтвердить данные можно через Госуслуги, Сбер ID, Tinkoff ID и Alfa ID.
Переключение между аккаунтами
Можно создать до трёх аккаунтов и быстро переключаться между ними с помощью VK ID — например, чтобы разделять рабочие и личные дела.
Оплата через VK Pay
Оплачивайте товары и услуги в один клик через VK Pay, а также храните свои карты, чеки, историю операций в личном кабинете VK ID.
Настройка авторизации через «Вконтакте»
Как настроить авторизацию посетителей сайта через «Вконтакте» в личном кабинете и для оформления заказа

- Зарегистрируйтесь во «Вконтакте».
- Перейдите на страницу добавления приложения «Вконтакте» .
- Напишите любое название, например, домен вашего сайта.
- Выберите платформу «Веб-сайт».
- Напишите адрес своего сайта и отдельно только его домен — без указания протокола.
- Перейдите в раздел «Настройки».




Если авторизация для этого сайта уже включена, перейдите по ссылке «Настройки авторизации».


- Откройте свой сайт в режиме браузера «инкогнито». Или в другом браузере, где вы не авторизованы ни в своем Вебасисте, ни во «Вконтакте».
- Перейдите по ссылке «Вход».
- Щелкните по иконке «Вконтакте».

Введите данные для входа в сервис.

5 комментариев
+2
Сергей BestForPet 15 января 2018 17:10 #
Ребят, поправьте инструкцию, теперь не обязательно заполнять п.7 В поле «Доверенный redirect URI» впишите адрес вида» Более, если прописываешь этот Url, то авторизация не работает.
+2
Зул 6 февраля 2018 21:30 #
Скорее всего у тебя такая печаль, если ты имея сертификат SSL указал протокол http, а если укажешь в этом поле https то все нормально работает, только что протестировал, хотя и без этого поля работает, зачем оно не знаю но у меня оно указано, у меня везде вместо http https.
+1
42na 19 февраля 2019 00:38 #
Благодарю, в поле было указывал HTTPS ничего не работало, удалил и все гуд
+2
evteev777 25 февраля 2018 08:25 #
Не получилось настроить авторизацию через VK, выдает ошибку: <"error":"invalid_request","error_description":"application is blocked">Пробовал и с www/без www, и с http/https, и с Доверенным redirect URI, и без него, даже удалял и заново создавал приложение — результат один и тот же. Естественно, «приложение включено и видно всем» ))) Перелогиниться в VK или зайти с другого браузера, как пишут в интернете, не помогло — ведь все равно захожу в режиме инкогнито. AdBlock отключен. Авторизация через Facebook завелась без проблем! Это решается??
"error":"invalid_request","error_description":"application>
+4
evteev777 25 февраля 2018 08:55 #
Разобрался сам! В настройках Webasyst надо было ввести ID приложения и Защищенный ключ, а я в эти поля вводил Защищенный ключ и Сервисный ключ доступа — просто похожи формы настроек Webasyst и приложения VK! Всегда читайте то, что написано мелким шрифтом! )))
HTTP Редактировано: 28.08.2020 в 04:45
HTTP Клиент существует в Easy VK со второй версии. Он нужен для тех случаев, когда нужно- сделать что-то такое, что не позволяет официальное API ВКонтакте. Так, например, на его основе я написал Audio API (удалено с 2.6.0 версии из-за отсутствия своевременных обновлений).
HTTP Клиент работает по принципу HTTP сессии, если Вы хотя бы частично знакомы с алгоритмом работы HTTP, то знаете, что сессия там живет, пока о Вас можно собрать хоть какую-то информацию*, например, кукисы. Когда Вы авторизуетесь в обычном браузере во Вконтакте, Вы создаете сессию, и информация об этой сессии хранится в куках браузера. Чтобы сессия «поддерживалась», браузер отправляет кукисы каждый раз, когда делает запрос, вместе с самим запросом. Таким образом, сервер ВКонтакте всегда будет знать, что сделать с этим запросом, и какой пользователь его выполнил
HTTP Клиент работает именно по принципу браузера, он авторизует Вас как бы «через браузер»*, и возвращает Вам объект для работы в этой авторизованной сессией. Так как авторизация происходит по протоколу HTTP, многие моменты могут перестать работать со временем, ведь ВКонтакте часто меняют свои внутренние и внешние алгоритмы, а я просто слоупок.
В общем HTTP Клиент — это мощная, крутая особенность Easy VK, но его поддержка — это требовательное дело и требует своевременного отклика на любые изменения ВКонтакте. Вы можете его использовать, а можете написать свой, на основе библиотеки node-fetch , это не сложно. Но будьте бдительны к ошибкам.
Использовать HTTP Клиент нужно так:
easyvk().then(vk => < vk.http.loginByForm((client) =>< // Первый шаг - авторизация в http клиенте, всегда client.someMethod(); // Пример работы с HTTP клиентом >) >)
http.loginByForm()
Для корректной работы HTTP авторизации, необходимо ВСЕГДА передавать в параметры авторизации easyvk логин и пароль пользователя, так как по access_token логин и пароль не получить из сессии, а сам логин и пароль не сохраняются в сессию в целях безопасности данных
Это самый основной метод http клиента, он запускает авторизацию во ВКонтакте, в браузере (Chrome), по Вашему текущему IP адресу. Метод возвращает объект , в случае корректной авторизации, resolve функция получит объект HTTPClient
Данные в HTTP клиенте с версии 2.6.0 не проверяются. Только, если нужно обновить сессию. То есть компонент не узнает, правильный или неправильный пароль вы ввели, потому как не делает доп. проверок.
В своем софте рекомендую делать такие проверки самостоятельно
< cookies: __dirname + "/my-cookies.json" // Путь к файлу, где будут храниться кукисы, // User-agent клиента, через который будут делаться запросы (можно взять браузера любого) userAgent: "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71. ", username: "ИМЯ_ПОЛЬЗОВАТЕЛЯ", // Если не настроен в основной фукнции password: "ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ", // Если не настроен в основной фукнции /** Хендлер капчи, работает также, как в основной функции Если не настроен, то берется хендер из основной функции */ captchaHandler: () =><>, captchaSid: 2424, // sid последней полученной капчи captchaKey: "wdwd", // Ключ для решения капчи reauth: true, // Нужно ли делать обновление сессии code: '2323', // Код для двухфакторной авторизации checkAuth: true, // Нужно ли в данный момент проверять кукисы на валидность checkCodeUrl: '' // URL адрес, на который будет отправлен код из СМС/звонка/сообщения в ВК >
Безопасная авторизация с получением access_token’а
Easy VK поддерживает авторизацию по данным официальных клиентов ВКонтакте, вроде приложения для Android / IOS. Но после введения ограничений на Messages API, ВКонтакте всячески стараются блокировать тех, кто авторизуется по данным таких приложений. Сделано это для того, чтобы спама было меньше. Я разрабатываю различный софт на основе API ВКонтакте, в основном во всех проектах я использую easyvk, и не каждый софт, мною разработанный, может называться «безопасным» с точки зрения модераторов ВКонтакте, поэтому я часто сталкиваюсь с блокировкой аккаунтов. Конечно, если аккаунт не используется для каких-то вредительских целей, он не будет заблокирован, но если он отправляет много запросов, то даже если это обычные запросы вроде stories.get, вероятно, аккаунт попадет в блокировку, только потому что авторизован по данным клиентов ВК неофициально. Easy VK пока что не научился подделывать «официальность» авторизации, но в качестве решения данной проблемы я предлагаю вам использовать авторизацию по HTTP клиенту, но с получением access_token’а. Такой метод авторизации не гарантирует, что вы будете иметь доступ ко всем методам API (включая те, что не описаны в документации), но такой метод гарантирует безопасность аккаунта на все 100%.
Метод
Метод заключается в том, что сначала мы делаем авторизацию по HTTP клиенту, а потом делаем OAuth авторизацию через https://oauth.vk.com/authorize, оставаясь внутри nodejs, и не открывая браузер и другой доп. софт.
Вот код, который получает токен по логину и паролю
const path = require('path') const USERNAME = '' const PASSWORD = '' /* >> async function context >) let client = await vk.http.loginByForm(< username: USERNAME, password: PASSWORD, cookies: path.join(process.cwd(), 'cookies.json'), reauth: true >) response = await client.fullRequest('https://oauth.vk.com/authorize', < client_id: 6121396, // ID приложения scope: 215985366, // Полный доступ response_type: 'token' >) let token = response.url.match(/access_token=([^&]+)/g) if (!token) < let text = await response.text() let loc = text.match(/location.href = "(.*)"\+addr/g) loc = loc[0].replace(/location.href = "(.*)"\+addr/g, " ") response = await client.fullRequest(loc, <>) > token = response.url.match(/#access_token=([^&]+)/g) token = token[0].replace('#access_token=', "") console.log(token)
Теперь Вам необходимо познакомиться с клиентом поближе, чтобы понять, что он может.
Easy VK © 2020 — Кирилл Новак