⬆️ ⬇️

Thinking article about entering the site without a password

On Habré more than once and not two articles were published about the need to allow the user to log in via Google / Twitter / Facebook , etc. As a matter of fact, progressive humanity has long decided that it is yesterday to require users to invent logins and passwords. In this article I want to discuss the problems that arise and how to solve them.



Small preface



At the moment I am one of the developers in the team of enthusiasts who have decided to write a kind of information and reference portal with social network elements for the Kohana php framework. Authentication is required to write a comment / feedback, participate in polls and ratings, etc. Just screwing the entrance through OpenID / OAuth is easy, interesting things appear when you start to think - what next?



Probably it is necessary to warn in advance that, in principle, it will be a question of theoretical research. As soon as we have the described mechanism ready, which will not be ashamed to show, we will show it.

')

Authentication



Database


We sketch out approximate database tables that will allow us to store the maximum possible amount of information that we can pull from the user.



users



Everything is clear, this is the main table for storing the user.







auth_data



This table is for working with external user accounts. For example, if user A has a Google account and another Twitter account, then we must provide two auth_data for one user account - so that nothing is lost!







Connections



Naturally, accounts should be tied to a specific user, so the user_id foreign key appears in the auth_data table.



Strangely enough, we also add the auth_id foreign key to the users table in order to bind the user to an account. What for? Thus, we want to highlight a certain primary ( primary ) account. For example, in order to automatically transfer some data from it to a user profile, or to implement autologin. The decision may seem controversial, but we currently consider it reasonable and useful.



Let me in, fiends!


And now - the actual authentication mechanism. Step by step.



  1. They clicked on the “login through” button, entered your OpenID or simply clicked on the provider’s image. We confirmed / proved to the provider that you are you.
  2. After the provider has sent you back to the site, you need to check the availability of this user in the database. What if you have already logged in? For this we use the service_id + service_name combination mentioned above. If the account is found, then everything is simple - we retrieve the user by user_id and forward.
  3. But no, the account previously did not fall into the field of view of our site, so let's quickly register it before it changes its mind.



    In auth_data , we record everything that the provider has given. Based on this data, we are trying to generate the username user. We save the new user, we specify the used account as primary . Hurray, we have a new user!


Well, what is there to discuss something?



Uh, quickly described the routine, let's look at various cases that require additional efforts from the programmer.



Remember me!


Often it becomes difficult to remember under what account previously visited the site. And why, let the site remember, it is more necessary for him. Therefore, after a successful login, we throw a cookie with a token in order to allow the user to log in automatically next time.



It’s not safe, you say, and you’ll probably be right. Therefore, when generating a token, we also save various information about the client (IP, User-Agent, etc. - there is a choice). If the user explicitly leaves the site (via the “exit” button), we kill the cookie. Well, in case of autologin, we need confirmation if the user wants to change some critical data (change soap or login). For extreme cases, you can draw the checkbox "do not remember me."



Naturally, in the case of OAuth, in order to use the service API (say, send a tweet to your account), a working token is needed, so you must either not use “memorization” in general, or, again, at the right time, send it to the provider for confirmation.



Remember? Not? Remember!


Even if the user logged out and emigrated to Albania for a long time did not appear, it is necessary to help him with authentication. Let's go back to the moment when the user is logged in. Above, I wrote about a special cookie. It turns out that her one is not enough - we throw the second. With a long duration. Inside we store the account identifier through which you entered.



Come back. And here this long-playing cookie will help us. Based on it, we prompt the user with something like “Well, you’ve logged in through Google, buddy!”. Naturally, if he chooses a different account, we will change the cookie to a new one. In the end, we are just a site, we do not mind.



Login from different accounts


Yeah, under a different account, you say! So we will duplicate users? No thanks. We need to fight this, and we will make every effort to that.



First of all, we look at the very long-lived cookie. She should tell us that not everything is clean, and potentially we are creating a second account. Therefore, we ask the user whether it is a separate account or an existing one. If it is separate, then after preliminary cleaning of the cookies and other information we create a new entry with zero mileage.



But if the user claims that it is still he, just for some reason he wants to enter in an unusual way for us (we have all the usual ones in auth_data , we remember this), then we will have to do a check. Offhand, I see several options - to offer to log in under the original account (ie, under primary - this is another reason for its indication), or send a confirmation code to the email (if it is indicated in the user profile). Formally, we can not require just the input under the primary , it is enough any of the already confirmed - as you wish.



If the user could not confirm his rights, then we delete the newly created account - there is nothing for us to lie.



Look at the mail!


Indeed, because the email address can be safely used as a user ID. Therefore, even if the cookie was not found, but the provider returned a familiar email to us - we offer the same dialogue with the choice of the path (merging accounts or a new one). Oh, it's a pity that not all accounts give away soap ...



Flag in your hands!


Why wait for a user to confuse their accounts? Let him indicate that he still has it in his storeroom. In the profile (only under the primary account?), We provide the opportunity to add more accounts that can be considered “our own”. And do not have to confuse the person with incomprehensible questions.



About Github


Did you know that Github supports OAuth v2? And he is, he can. For our project, this service is special, you might say, darling. As soon as the user logs in via Github, we immediately begin an additional lick.



  1. I did not talk about this, but in the users table we also store the developer_id field. This is the key to communicate with the developers table (hello to you, Cap!), In it we store the developers that Github passed us through our API. The fact is that we collect the developed modules for Kohana (this is one of the main tasks of the project), so it is very useful to know that some of the visitors are the author of some modules.
  2. It is never superfluous to collect additional information from the user. And if the user is a programmer, then this information becomes even more useful (khe-khe). After successful registration, we remind Giethabber that we have N modules of his authorship, and he can edit some data (compatibility, versions, description, etc.). No, not so. We can handle it ourselves. But we will still send notifications to the developer about new modules added for his authorship (ok, ok, we'll also make the option to turn off notifications).




What am I talking about?



Naturally, there will be many pitfalls. I would like to discuss in advance the described algorithms and possible jambs / omissions, both from the site visitor’s side (how convenient this scheme is, there are suggestions, or maybe you’re constantly straining something on such sites?) And from the developers ’point of view (which they implemented at home, where there may be shoals). Indeed, in the comments to articles on Habré, there is often much more useful information than in the article itself.

Source: https://habr.com/ru/post/122012/



All Articles