Authorization in VK using login and password in Python.


What's happened?

Hello dear reader.
If you have at least once had the opportunity to work with the VKontakte API and at the same time write everything in python, probably authorizing the application forced you to do several squats, after which you either don’t feel your legs and faint, or pump up your quadriceps and still break through the API, like Van Damm. For some reason, this seemingly most unremarkable stage initially takes a huge amount of effort and time. My task: to help Habr readers avoid leg injuries.

Next, I propose to consider a small library that allows you to authorize your application for a specific user in one line and get an access_token. At the end of the article there is a link to the github repository of this library with a quickstart in the README file.

Authorization via VKontakte

What percentage of your site's users are also VKontakte users? How many people do you think don’t write / comment / add anything (underline as necessary), just because they are too lazy to register on another incomprehensible site for the 100th time? I suggest answering these 2 questions for yourself before scolding VKontakte and Open API. In my case, about 1,500 people come to the site from VKontakte every day, and it seems to me that it is my duty to provide them with a simple and convenient way to register.

It is unlikely that I will discover anything new, but if at least one more site becomes a little more convenient after this article, then I have not wasted my time writing this text. I wrote the Open API authorization module for the site in PHP, so all the code will be in it. There was also an article for Django.

The source code for the simplest example is available on github. I won’t reprint it here, I’ll just briefly tell you how it works.

The main work is performed by the Auth_Vkontakte class, which contains 3 methods:

  • is_auth
    — Returns the VKontakte user ID, if the user is not authorized through the Open API — returns false
  • logout
    - Logs the user out by clearing the cookie that VKontakte adds. I haven't found a better way. The Open API has a logout method, but it only worked for me every now and then.
  • render_login_form
    — Returns the HTML code for displaying the “Login VKontakte” button, including all the necessary scripts.

You, of course, will also have to add vkontakte support to your site engine, for example, add the “vk_id” field to the user nameplate, which will store the VKontakte user ID.
The algorithm for working in real conditions is something like this:

  1. After the VKontakte user logs in, we transfer him to a separate page (in my case it’s vk.php), where we check whether the user with the same vk_id is already registered. If not, we show him a simplified registration form (for example, only login and email). Then we create a user and transfer the newly registered visitor to the main page.
  2. We create a backend that will check the VKontakte cookie via Auth_Vkontakte::is_auth, in the case when the visitor has not entered your site in any way. If is_auth returns a value other than false and a user with this id is registered on your site, we authorize users through your system. If it suddenly turns out that he is not registered, we show the registration form again.
  3. When logging out, in addition to your cookie, we also delete the cookie from VKontakte (Auth_Vkontakte::logout method)

In general, it seems to me that any documentation for any API should begin with such examples.
The VKontakte developers, however, do not think so and it is impossible to understand the Open API from their documentation. In fact, I didn’t use it - I only read everything in the source code on durov.at. Really, the VKontakte company cannot afford to hire a normal technical writer who would write examples and normal manuals, and not dry lists of functions with a brief description of the parameters that it accepts? In order to try a test example in action (which, however, will not show anything except your ID), just download the sources and configure a local web server at the address: openapi.lc (add to hosts: 127.0.0.1 openapi.lc).

If someone liked it and found it useful, I will also write an article about FacebookConnect.

Task

We want a small module that allows you to perform authorization beautifully, universally and as reliably as possible, and which is very easy to use. It is worth saying that this solution is an improvement and generalization of the option proposed in this article.

So, we use python3.5, a library for html requests requests and getpass for hidden password entry.

Our task: contact the correct address several times, parse each time

, send a response and finally receive the desired access_token.

Main advantages of identification

Both site owners and its users have benefits. The advantages for the owner are:

  1. Anti-spam protection (screening out spam bots).
  2. Restriction of rights to use additional services. For commercial sites, authorization is simply necessary, since they provide their services for money.
  3. The ability to get to know the user, which also has its advantages: geographic, demographic and other information about visitors, which allows you to set up the site correctly, select the most effective advertising and keywords.

Benefits for users:

  1. Also anti-spam protection.
  2. Ability to recognize your interlocutor.
  3. Additional features such as filling out a profile, uploading a photo, other files, and so on.

So, we figured out what authorization is. That this is a means of protecting user data. For websites it is of great importance. Based on this, you should take the situation seriously if your authorization fails.

You've probably already heard that today you can get information about almost any person through social networks

, and especially through VKontakte. Moreover, very often it is not at all necessary to be registered in it. It is enough to type the last name, first name and city of residence of the desired person in the search engine and that’s it.

I won’t go into detail about why this is bad (anyone who wants to can read the article I wrote on this subject about protecting a VKontakte account), but I’ll focus on how to make life even a little more difficult for curious people.

Implementation

Let's start by creating a class.
During initialization, we will require a list of “permissions” that the application wants to access, the id of this application and the VK API version. Plus, we’ll add several optional parameters, the meaning of each of which will become clearer later. Method __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')

As mentioned in the already mentioned article, we need to skillfully manage cookies and redirects. The requests library does all this for us with an object of the Session class. Let's create one for ourselves in the self.session field. To parse an html document, use the standard HTMLParser class from the html.parser module. A class (FormParser) was also written for the parser, which makes little sense to analyze, since it almost completely repeats the one from the mentioned article. The only significant difference is that the one used here allows you to gracefully reject application authorization at the last step if you suddenly change your mind.

The user_id and access_token fields will be filled in after successful authorization, response stores the result of the last html request.

We will provide the library user with one single method – authorize, which performs 3 steps:

  1. application authorization request
  2. user authorization 2.1 entering a key code in case of two-factor authentication
  3. confirmation of permission to use permissions

Let's go through each step.

Step 1. Application authorization request

We carefully compose the request url (you can read about the parameters here), send the request and parse the resulting html.

Authorize Method for Step 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 = '{0}?client_id={1}&scope={2}&redirect_uri={3}&display={4}&v={5}&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')

Step 2. User authorization

The _log_in() and _two_fact_auth() methods have been implemented for [un]successfully authorizing a user in VK if he is not authorized (and he is definitely not authorized). Both methods use the previously defined fields email, pswd, two_factor_auth and security_code. If any of the fields were not supplied as an argument when initializing the VKAuth class object, they will be asked to enter them in the console, and if unsuccessful, they will be asked to enter them again. Two-factor authentication is optional and disabled by default, and our module notifies the user of its presence with an error.

The authorize method for Step 2 (continued from Step 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 method for Step 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({'email': self.email, 'pass': self.pswd}) 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

Method _two_fact_auth for Step 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({'code': self.security_code}) if not self._parse_form(): raise RuntimeError('No element found. Please, check url address')

Creating a new VKontakte application

Before we write any code, we need to register the new application. This is done simply, go to your profile, go to the application section and click on the “Manage” button in it. In this section you will see a list of all the applications that you use and the “Create application” button, click on it. Fill in the name and select “Website”.

After this, two new fields will appear, which we also fill out and click “Connect site”. In the next window you will have to confirm your registration.

This is how quickly and easily the new VKontakte application is registered. Now go to settings and copy the application ID and secure key into notepad. This is where work with the social network ends.

We create the necessary pages

Before we post chunks with code fragments, we will create five pages.

  • Login page (1):
    page containing the login form
  • Password reset (2):
    page where users can request password recovery
  • Password reset handler (3):
    a hidden page that will actually reset the password. Users will not see it.
  • Users-only page (4):
    a page whose contents are visible only to authorized users of the site
  • Logout page (5):
    The page the user is redirected to after successfully logging out

This is what my resource tree looks like at the moment.
Keep in mind that your resource ID will be different. In this example, there is nothing except pages for the “Login” component. Next, we need to assign the correct rights to users and resources.

Create the necessary user groups and resource groups

MODX Revo has a very flexible permissions system when it comes to user permissions, but in this topic we will only do what we need without going too deep into the topic. So, let's get started. 1. Security → Resource Groups
Click on “Create a resource group” and name it “For users only”, for example. Click “Save” and that’s it, we don’t change anything else on this page.

2. Security → Access Control
On the first “User Groups” tab, click on “New User Group”. Let’s name the new group “Users” and click “Save”. The user group will have access to "Users Only" resources. We will find out why we need this a little later in this lesson.


3. On the same page (
Security → Access Control
), right-click on the created user group and select “Edit user group”.
Next, go to the “Access to resource groups” tab and click on “Add resource group”. For proper operation, there must be at least the following parameters: Resource group:
Users only (the one we just created)
Minimum role:
Member-9999
Access policy:
Load, List and View
Context:
web And save.
4. Security → User Management
We create a “new user” and thereby check how the differentiation of access rights for users will work.
In this case, use a simple login and password, because, as I wrote above, it is important for us to make sure that the new user is in the “Users” group. To do this, go to the “Access Rights” tab and click on “Add user to group”. User group:
Users
Role:
Member Then click “save” in the window, and then
again
in the right corner of the control panel. This should ensure that a new user can log in with “User” rights to view the page with “Users Only” rights. Now let's go back to the pages to add snippets and code snippets to the corresponding pages.

Rating
( 1 rating, average 5 out of 5 )
Did you like the article? Share with friends:
For any suggestions regarding the site: [email protected]
Для любых предложений по сайту: [email protected]