Skip to content

Commit e7a0a79

Browse files
committed
Update cookies format
1 parent 55849ea commit e7a0a79

2 files changed

Lines changed: 92 additions & 54 deletions

File tree

vk_api/utils.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
except ImportError:
1313
import json
1414

15+
from http.cookiejar import Cookie
16+
1517

1618
def search_re(reg, string):
1719
""" Поиск по регулярке """
@@ -53,3 +55,36 @@ def sjson_dumps(*args, **kwargs):
5355
kwargs['separators'] = (',', ':')
5456

5557
return json.dumps(*args, **kwargs)
58+
59+
60+
HTTP_COOKIE_ARGS = [
61+
'version', 'name', 'value',
62+
'port', 'port_specified',
63+
'domain', 'domain_specified',
64+
'domain_initial_dot',
65+
'path', 'path_specified',
66+
'secure', 'expires', 'discard', 'comment', 'comment_url', 'rest', 'rfc2109'
67+
]
68+
69+
70+
def cookie_to_dict(cookie):
71+
cookie_dict = {
72+
k: v for k, v in cookie.__dict__.items() if k in HTTP_COOKIE_ARGS
73+
}
74+
75+
cookie_dict['rest'] = cookie._rest
76+
77+
return cookie_dict
78+
79+
80+
def cookie_from_dict(d):
81+
return Cookie(**d)
82+
83+
84+
def cookies_to_list(cookies):
85+
return [cookie_to_dict(cookie) for cookie in cookies]
86+
87+
88+
def set_cookies_from_list(cookie_jar, l):
89+
for cookie in l:
90+
cookie_jar.set_cookie(cookie_from_dict(cookie))

vk_api/vk_api.py

Lines changed: 57 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616

1717
import jconfig
1818
from .exceptions import *
19-
from .utils import code_from_number, search_re, clean_string
19+
from .utils import (
20+
code_from_number, search_re, clean_string,
21+
cookies_to_list, set_cookies_from_list
22+
)
2023

2124
DELAY = 0.34 # ~3 requests per second
25+
2226
TOO_MANY_RPS_CODE = 6
2327
NEED_VALIDATION_CODE = 17
2428
HTTP_ERROR_CODE = -1
@@ -68,15 +72,14 @@ def __init__(self, login=None, password=None, token=None,
6872
self.login = login
6973
self.password = password
7074

71-
self.sid = None
7275
self.token = {'access_token': token}
7376

7477
self.api_version = api_version
7578
self.app_id = app_id
7679
self.scope = scope
7780
self.client_secret = client_secret
7881

79-
self.settings = config(self.login, filename=config_filename)
82+
self.storage = config(self.login, filename=config_filename)
8083

8184
self.http = requests.Session()
8285
self.http.headers.update({
@@ -97,6 +100,13 @@ def __init__(self, login=None, password=None, token=None,
97100

98101
self.logger = logging.getLogger('vk_api')
99102

103+
@property
104+
def sid(self):
105+
return (
106+
self.http.cookies.get('remixsid') or
107+
self.http.cookies.get('remixsid6')
108+
)
109+
100110
def auth(self, reauth=False, token_only=False):
101111
""" Аутентификация
102112
@@ -126,8 +136,12 @@ def auth(self, reauth=False, token_only=False):
126136

127137
self.logger.info('Auth with login: {}'.format(self.login))
128138

129-
self.sid = self.settings.remixsid
130-
self.token = self.settings.setdefault('token', {}).get(str(self.scope))
139+
set_cookies_from_list(
140+
self.http.cookies,
141+
self.storage.setdefault('cookies', [])
142+
)
143+
144+
self.token = self.storage.setdefault('token', {}).get(str(self.scope))
131145

132146
if not token_only:
133147
self._auth_cookies(reauth=reauth)
@@ -139,7 +153,7 @@ def _auth_cookies(self, reauth=False):
139153
if reauth:
140154
self.logger.info('Auth forced')
141155

142-
self.settings.clear_section()
156+
self.storage.clear_section()
143157

144158
self.vk_login()
145159
self.api_login()
@@ -253,25 +267,11 @@ def vk_login(self, captcha_sid=None, captcha_key=None):
253267

254268
self.twofactor(response)
255269

256-
remixsid = (
257-
self.http.cookies.get('remixsid') or
258-
self.http.cookies.get('remixsid6')
259-
)
260-
261-
if remixsid:
270+
if self.sid:
262271
self.logger.info('Got remixsid')
263272

264-
self.settings.remixsid = remixsid
265-
266-
# Нужно для авторизации в API
267-
self.settings.forapilogin = {
268-
'p': self.http.cookies['p'],
269-
'l': self.http.cookies['l']
270-
}
271-
272-
self.settings.save()
273-
274-
self.sid = remixsid
273+
self.storage.cookies = cookies_to_list(self.http.cookies)
274+
self.storage.save()
275275
else:
276276
self.logger.info('Unknown auth error')
277277

@@ -358,14 +358,7 @@ def check_sid(self):
358358
self.logger.info('No remixsid')
359359
return
360360

361-
url = 'https://vk.com/feed2.php'
362-
self.http.cookies.update({
363-
'remixsid': self.sid,
364-
'remixlang': '0',
365-
'remixsslsid': '1'
366-
})
367-
368-
response = self.http.get(url).json()
361+
response = self.http.get('https://vk.com/feed2.php').json()
369362

370363
if response['user']['id'] != -1:
371364
self.logger.info('remixsid is valid')
@@ -376,20 +369,21 @@ def check_sid(self):
376369
def api_login(self):
377370
""" Получение токена через Desktop приложение """
378371

379-
if not self.sid or not self.settings.forapilogin:
380-
raise AuthError('API authorization error (no cookies)')
381-
382-
url = 'https://oauth.vk.com/authorize'
383-
values = {
384-
'client_id': self.app_id,
385-
'scope': self.scope,
386-
'response_type': 'token',
387-
}
388-
389-
self.http.cookies.update(self.settings.forapilogin)
390-
self.http.cookies.update({'remixsid': self.sid})
391-
392-
response = self.http.get(url, params=values)
372+
if not self.sid:
373+
raise AuthError('API auth error (no remixsid)')
374+
375+
for cookie_name in ['p', 'l']:
376+
if not self.http.cookies.get(cookie_name, domain='.login.vk.com'):
377+
raise AuthError('API auth error (no login cookies)')
378+
379+
response = self.http.get(
380+
'https://oauth.vk.com/authorize',
381+
params={
382+
'client_id': self.app_id,
383+
'scope': self.scope,
384+
'response_type': 'token'
385+
}
386+
)
393387

394388
if 'access_token' not in response.url:
395389
url = search_re(RE_TOKEN_URL, response.text)
@@ -398,20 +392,29 @@ def api_login(self):
398392
response = self.http.get(url)
399393

400394
if 'access_token' in response.url:
401-
params = response.url.split('#')[1].split('&')
402-
403-
token = {}
404-
for i in params:
405-
x = i.split('=')
406-
token.update({x[0]: x[1]})
395+
params = response.url.split('#', 1)[1].split('&')
396+
token = dict(param.split('=', 1) for param in params)
407397

408-
self.settings.setdefault('token', {})[str(self.scope)] = token
409-
self.settings.save()
410398
self.token = token
411399

400+
self.storage.setdefault('token', {})[str(self.scope)] = token
401+
self.storage.save()
402+
412403
self.logger.info('Got access_token')
404+
405+
elif 'oauth.vk.com/error' in response.url:
406+
error_data = response.json()
407+
408+
error_text = error_data.get('error_description')
409+
410+
# Deletes confusing error text
411+
if error_text and '@vk.com' in error_text:
412+
error_text = error_data.get('error')
413+
414+
raise AuthError('API auth error: {}'.format(error_text))
415+
413416
else:
414-
raise AuthError('Authorization error (api)')
417+
raise AuthError('Unknown API auth error')
415418

416419
def server_auth(self):
417420
""" Серверная авторизация """

0 commit comments

Comments
 (0)