Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 71 additions & 6 deletions vk_api/vk_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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+).*?<')
Expand Down Expand Up @@ -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: страница с приглашением к аутентификации
Expand All @@ -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',
Expand All @@ -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'))
Expand Down Expand Up @@ -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)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sometimes goes trough some redirects

 0.49 GET https://vk.com/feed.php ... None 302 [] 
 0.47 GET https://login.vk.com/?role=fast&_origin= ... None 302 [] 
 0.18 GET https://vk.com/login.php?slogin_h= ... None 302 [] 
 0.15 GET https://vk.com/feed.php ... None 200 [] 


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 приложение """
Expand Down Expand Up @@ -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))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, on the first run it failed to parse it

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

response status code is 429 Too Many Requests

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe need to add a delay between requests?

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']
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And once failed with 🤔

{"error":{"error_code":5,"error_msg":"User authorization failed: access_token was given to another ip address","error_text":"Failed to connect to network. Please close the page and try again.",


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)
Expand Down