Formulation of the problem
Some time ago, as a duty
of work, the question “Has it necessary to do authorization on a new project through third-party services?” Came up for discussion. The brain, agitated by beautiful pop-up windows, widgets and other decorations, appealingly demanding “Enter through me!”, Was of course with both hands, and modern web-dvololnye (and even, pah pahu, webtrinolnye, maybe?) The development trends of large portals , as it were, hinted. However, I knowingly said that everything began with a discussion, for where there are disputes, there are also stumbling blocks. We found such a stone here too.
Suppose there is a beautiful socket on the site, such as
loginses , or simply separate authorization widgets, for example, through contact, twitter, facebook and their ilk. Easy to log in? Of course. But at the same time, if a person enters immediately from all these accounts (at the same time or not, is not the point), for the system they will be different people, and consequently, clones of the same person, whose account, perhaps, doesn’t exist on the site .
It would seem, what's the difference, register an account on the site, or enter through external resources?
And here it all depends on the essence of our project. If we have a very narrowly focused website, on which, for example, you can read any news and write off the
bastard in the comments, we can be satisfied with external services. And if every user on the site is a whole world, with its articles, ads, ratings, distilleries and aerospace shuttles?
')
Star Warriors - Attack of the Clones
Immediately I warn you, this article is still only purely theoretical in nature, and was created with the aim to listen to the ideas and suggestions of all who have read it.Search for a solution
Skimming over available resources and examining the API of the most common services, it was found out (not in the sense, "Wow, damn it! And I did not know!", But in the sense of "Aha ... And here it is, and here, and even here, too "), that they all work on the same principle.
A person sends a request through an external resource widget, which, in general, returns a user ID on this resource, some account data, and a secret key generated according to the algorithm available to developers. And this data the same developer can use on the site in any way.
After a very vague googling and analyzing the results, a method was invented that, in principle, solves the task of unambiguously establishing the identity of the user logged into the site - binding.
Cooking
I will try to describe the algorithms given below in general terms, but since I am currently working with the kohana framework, I can randomly describe the process in terms of this framework, so do not swear much.
So first, we need
three tables in the database .
The first table will be called "
Users " and, oddly enough, will include a list of users registered on our site. Its structure can be any, but it must have required fields
- User ID
- Login (or any other field, unique, acting as a login)
- Password (encrypted or not, decide for
yourself )
The second table will include the
list of external resources allowed on our site , such as contact, twitter, etc., it should look like this:
- resource ID
- The name of the resource (for example, "Vkontakte")
- The machine name of the resource (for example, “vkontakte”)
- Place the user ID in the link (for example, "vkontakte.ru/{ ID}")
- The key (ID) of the application (in our case, our site) on this resource
And the
third table , and, perhaps, the most important one, is the "
Links ", which will include the correspondence of the user account on our site to the account on an external resource. She looks like this:
- ID of communication (classic, yes?)
- resource ID
- User ID on our site
- ID (or ID) of the user on the external resource
Also, in the future, for each of the resources provided on our site, we must have appropriate views (some popup windows and other wonders) that will display a particular widget, as well as functions (classes, helpers). , modules or whatever) that will calculate and check the corresponding API key, but more on that later.
Some algorithms
So now the action itself. Let's start with the easiest!
Suppose we have a website on which we see the traditional login / registration form, as well as a panel with some widgets of some external resources.
When a person enters / registers on our website traditionally, after going through the final authorization procedure, he will get to our website or immediately to his panel, where he will see the settings section. Having entered this section, he will see a panel there, for example, “Profiles on external resources”, where the fields created in our table of external resources will be.
Suppose the user selected the "Vkontakte" field, and entered his ID there. How the process starts - if you lose the focus of the input, or when you press a button, or thanks to a UFO - it does not matter to us, the consequences are important. We run the appropriate authorization procedure for the corresponding widget (pop-up window, ajax-request for the desired script or something else).
If the user is already authorized on an external resource, the necessary data will be returned to us, otherwise, the user will have to log in, and we will still receive long-awaited data. And here begins the witch.
The
key returned from the resource is some kind of hash or, what's more terrible, from the aggregate of data, which, in particular, contains the user ID on the remote resource. To begin, we use the key generation procedure created by us (here, for which we needed the machine name to call the corresponding procedures) for a specific resource, we create this key using the identifier entered by the user on our site. Then we compare the key that came from the resource with ours.
If the two keys match, and the entered identifier coincides with the received one in the open, it means that we are really the owner of the specified account. In this case, we create a row in the table "
Links ", and the entered identifier becomes unique, no one else can enter the same (as an option, in the case of an input attempt, show an error that someone already has such an ID, and output link to this person).
In the case when the keys didn’t match, it’s worth scolding a person for trying to kidnap someone’s identifier, or politely ask again if he entered under his account, or, out of habit, climbed onto the page of his girlfriend / boyfriend.
The above is true for any external resource, the ID of which the user wants to specify.
The easiest option finished. We proceed to the most difficult part - authorization through external control without registering on the site.
In this case, in this method, there is no need to create a physical account. As soon as a person makes an entry to the site, say, through the same contact, a session will open for him and a large warning message will appear to him, like:
This account % resource name% is not tied to any of the accounts registered on the site. You can link it to your account right now, or register a new one .Actually, everything will not be limited to the issuance of this window, because in order to motivate the user to bind themselves to any account, we will also cut the rights for him so that he can, for example, only watch content. Well, or something else like that. Of course, when a person clicks on one of the links in the warning, he will be able to calmly or enter his login password, and the identifier under which he currently entered the site will automatically link to his account, as in the case of registration.
findings
Say, severely limit the user without a real account on the site? I agree.
But, having passed a simple registration procedure, he will subsequently be able to log in with one click through various resources, and will always get into his account on the site, and the binding process from an existing account generally takes moments. In any case, even a binding warning can be implemented in the best traditions of webbangles, so that it doesn’t particularly afflict the eyes, but also hints at the same time.
Unfortunately, at the moment I don’t have time to implement the above algorithm, but if I do it, but first of all under the Kohana framework, now I’ll be happy to hear constructive criticism and suggestions how and what can be improved here. Thanks for attention