def _pass_twofactor(self, auth_response): """ Двухфакторная аутентификация :param auth_response: страница с приглашением к аутентификации """ code, remember_device = self.error_handlers[TWOFACTOR_CODE]() auth_hash = search_re(RE_AUTH_HASH, auth_response.text) values = { 'act': 'a_authcheck_code', 'al': '1', 'code': code, 'remember': int(remember_device), 'hash': auth_hash, } response = self.http.post('https://vk.com/al_login.php', values) response_parsed = response.text.split('<!>') if response_parsed[4] == '4': # OK return self.http.get('https://vk.com/' + response_parsed[5]) elif response_parsed[4] == '8': # Incorrect code return self._pass_twofactor(auth_response) raise TwoFactorError('Two factor authentication failed')
def _pass_twofactor(self, auth_response): """ Двухфакторная аутентификация :param auth_response: страница с приглашением к аутентификации """ code, remember_device = self.error_handlers[TWOFACTOR_CODE]() auth_hash = search_re(RE_AUTH_HASH, auth_response.text) values = { 'act': 'a_authcheck_code', 'al': '1', 'code': code, 'remember': int(remember_device), 'hash': auth_hash, } response = self.http.post('https://vk.com/al_login.php', values) data = json.loads(response.text.lstrip('<!--')) status = data['payload'][0] if status == '4': # OK path = json.loads(data['payload'][1][0]) return self.http.get('https://vk.com' + path) elif status in [0, '8']: # Incorrect code return self._pass_twofactor(auth_response) elif status == '2': raise TwoFactorError('Recaptcha required') raise TwoFactorError('Two factor authentication failed')
def _api_login(self): """ Получение токена через Desktop приложение """ if not self._sid: raise AuthError('API auth error (no remixsid)') for cookie_name in ['p', 'l']: if not self.http.cookies.get(cookie_name, domain='.login.vk.com'): raise AuthError('API auth error (no login cookies)') response = self.http.get( 'https://oauth.vk.com/authorize', params={ 'client_id': self.app_id, 'scope': self.scope, 'response_type': 'token' } ) if 'act=blocked' in response.url: raise AccountBlocked('Account is blocked') if 'access_token' not in response.url: url = search_re(RE_TOKEN_URL, response.text) if url: response = self.http.get(url) if 'access_token' in response.url: params = response.url.split('#', 1)[1].split('&') token = dict(param.split('=', 1) for param in params) self.token = token self.storage.setdefault( 'token', {} ).setdefault( 'app' + str(self.app_id), {} )['scope_' + str(self.scope)] = token self.storage.save() self.logger.info('Got access_token') elif 'oauth.vk.com/error' in response.url: error_data = response.json() error_text = error_data.get('error_description') # Deletes confusing error text if error_text and '@vk.com' in error_text: error_text = error_data.get('error') raise AuthError('API auth error: {}'.format(error_text)) else: raise AuthError('Unknown API auth error')
def _pass_security_check(self, response=None): """ Функция для обхода проверки безопасности (запрос номера телефона) :param response: ответ предыдущего запроса, если есть """ self.logger.info('Checking security check request') if response is None: response = self.http.get('https://vk.com/settings') if 'security_check' not in response.url: self.logger.info('Security check is not required') return response phone_prefix = clear_string(search_re(RE_PHONE_PREFIX, response.text)) phone_postfix = clear_string( search_re(RE_PHONE_POSTFIX, response.text)) code = None if self.login and phone_prefix and phone_postfix: code = code_from_number(phone_prefix, phone_postfix, self.login) if code: number_hash = search_re(RE_NUMBER_HASH, response.text) values = { 'act': 'security_check', 'al': '1', 'al_page': '3', 'code': code, 'hash': number_hash, 'to': '' } response = self.http.post('https://vk.com/login.php', values) if response.text.split('<!>')[4] == '4': return response if phone_prefix and phone_postfix: raise SecurityCheck(phone_prefix, phone_postfix) raise SecurityCheck(response=response)
def _vk_login(self, captcha_sid=None, captcha_key=None): """ Авторизация ВКонтакте с получением cookies remixsid :param captcha_sid: id капчи :type captcha_key: int or str :param captcha_key: ответ капчи :type captcha_key: str """ self.logger.info('Logging in...') if not self.password: raise PasswordRequired('Password is required to login') self.http.cookies.clear() # Get cookies response = self.http.get('https://vk.com/') values = { 'act': 'login', 'role': 'al_frame', '_origin': 'https://vk.com', 'utf8': '1', 'email': self.login, 'pass': self.password, 'lg_h': search_re(RE_LOGIN_HASH, response.text) } if captcha_sid and captcha_key: self.logger.info('Using captcha code: {}: {}'.format( captcha_sid, captcha_key)) values.update({ 'captcha_sid': captcha_sid, 'captcha_key': captcha_key }) response = self.http.post('https://login.vk.com/', values) if 'onLoginCaptcha(' in response.text: self.logger.info('Captcha code is required') captcha_sid = search_re(RE_CAPTCHAID, response.text) captcha = Captcha(self, captcha_sid, self._vk_login) return self.error_handlers[CAPTCHA_ERROR_CODE](captcha) if 'onLoginReCaptcha(' in response.text: self.logger.info('Captcha code is required (recaptcha)') captcha_sid = str(random.random())[2:16] captcha = Captcha(self, captcha_sid, self._vk_login) return self.error_handlers[CAPTCHA_ERROR_CODE](captcha) if 'onLoginFailed(4' in response.text: raise BadPassword('Bad password') if 'act=authcheck' in response.text: self.logger.info('Two factor is required') response = self.http.get('https://vk.com/login?act=authcheck') self._pass_twofactor(response) if self._sid: self.logger.info('Got remixsid') self.storage.cookies = cookies_to_list(self.http.cookies) self.storage.save() else: raise AuthError( 'Unknown error. Please send bugreport to [email protected]') response = self._pass_security_check(response) if 'act=blocked' in response.url: raise AccountBlocked('Account is blocked')