From e6ba6daaa8de51ad448e019f91f77e3b7183aebf Mon Sep 17 00:00:00 2001 From: cerg2010cerg2010 Date: Sat, 1 Jul 2023 23:34:48 +0300 Subject: [PATCH] Fix cookie login - Support captcha on twofactor path - Fix sid verification - Fix OAuth response parsing --- vk_api/vk_api.py | 77 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/vk_api/vk_api.py b/vk_api/vk_api.py index e4344e4..fd37a45 100644 --- a/vk_api/vk_api.py +++ b/vk_api/vk_api.py @@ -34,6 +34,7 @@ RE_NUMBER_HASH = re.compile(r"al_page: '3', hash: '([a-z0-9]+)'") RE_AUTH_HASH = re.compile(r"Authcheck\.init\('([a-z_0-9]+)'") RE_TOKEN_URL = re.compile(r'location\.href = "(.*?)"\+addr;') +RE_AUTH_TOKEN_URL = re.compile(r'window\.init = ({.*?});') RE_PHONE_PREFIX = re.compile(r'label ta_r">\+(.*?)<') RE_PHONE_POSTFIX = re.compile(r'phone_postfix">.*?(\d+).*?<') @@ -342,7 +343,7 @@ def _vk_login(self, captcha_sid=None, captcha_key=None): if 'act=blocked' in response.url: raise AccountBlocked('Account is blocked') - def _pass_twofactor(self, auth_response): + def _pass_twofactor(self, auth_response, captcha_sid=None, captcha_key=None): """ Двухфакторная аутентификация :param auth_response: страница с приглашением к аутентификации @@ -361,6 +362,15 @@ def _pass_twofactor(self, auth_response): 'hash': auth_hash, 'remember': int(remember_device), } + if captcha_sid and captcha_key: + self.logger.info( + 'Using captcha code: {}: {}'.format( + captcha_sid, + captcha_key + ) + ) + values['captcha_sid'] = captcha_sid + values['captcha_key'] = captcha_key response = self.http.post( 'https://vk.com/al_login.php?act=a_authcheck_code', @@ -377,6 +387,14 @@ def _pass_twofactor(self, auth_response): return self._pass_twofactor(auth_response) elif status == '2': + if data['payload'][1][1] != 2: + # Regular captcha + self.logger.info('Captcha code is required') + + captcha_sid = data['payload'][1][0][1:-1] + captcha = Captcha(self, captcha_sid, self._pass_twofactor, (auth_response,)) + + return self.error_handlers[CAPTCHA_ERROR_CODE](captcha) raise TwoFactorError('Recaptcha required') raise TwoFactorError(get_unknown_exc_str('2FA; unknown status')) @@ -435,13 +453,15 @@ def check_sid(self): self.logger.info('No remixsid') return - response = self.http.get('https://vk.com/feed2.php').json() + feed_url = 'https://vk.com/feed.php' + response = self.http.get(feed_url) - if response['user']['id'] != -1: - self.logger.info('remixsid is valid') - return response + if response.url != feed_url: + self.logger.info('remixsid is not valid') + return False - self.logger.info('remixsid is not valid') + self.logger.info('remixsid is valid') + return True def _api_login(self): """ Получение токена через Desktop приложение """ @@ -469,6 +489,51 @@ def _api_login(self): if url: response = self.http.get(url) + elif 'redirect_uri' in response.url: + response = self.http.get(response.url) + auth_json = json.loads(search_re(RE_AUTH_TOKEN_URL, response.text)) + return_auth_hash = auth_json['data']['hash']['return_auth'] + response = self.http.post( + 'https://login.vk.com/?act=connect_internal', + { + 'uuid': '', + 'service_group': '', + 'return_auth_hash': return_auth_hash, + 'version': 1, + 'app_id': self.app_id, + }, + headers={'Origin': 'https://id.vk.com'} + ) + connect_data = response.json() + if connect_data['type'] != 'okay': + raise AuthError('Unknown API auth error') + auth_token = connect_data['data']['access_token'] + response = self.http.post( + 'https://api.vk.com/method/auth.getOauthToken', + { + 'hash': return_auth_hash, + 'app_id': self.app_id, + 'client_id': self.app_id, + 'scope': self.scope, + 'access_token': auth_token, + 'is_seamless_auth': 1, + 'v': '5.207' + } + ) + + self.token = response.json()['response'] + + self.storage.setdefault( + 'token', {} + ).setdefault( + 'app' + str(self.app_id), {} + )['scope_' + str(self.scope)] = self.token + + self.storage.save() + + self.logger.info('Got access_token') + return + if 'access_token' in response.url: parsed_url = urllib.parse.urlparse(response.url)