Answer the question
In order to leave comments, you need to log in
How to write authorization/authentication correctly?
What can you read in order to understand how to organize everything correctly?
1. From complete scratch. User enters login + password:
1.1 What to write in cookies/session?
1.2 How to check whether the user is authorized or not on each page?
1.3 If you want the user to have only simultaneous access from one device - how to be?
1.4 And if from several?
2. The user logs in via VK
1.1 What to write in cookies / session?
1.2 How to check whether the user is authorized or not on each page?
A big request is to answer all the points, or give a resource / article / where / what to read in order to answer all the points.
Thanks in advance for your informative response!
Answer the question
In order to leave comments, you need to log in
There are two options for storing data about an authorized user:
1) In cookies (as it is used by default in asp.net): the necessary data (claims) are encrypted by machineKey and given to the user in http-only cookies, so they are sent with each request to the server, decrypted and then can be checked in the required places.
pluses: completely stateless, no need to access the database
2) Session key: after successful authentication, we authorize the user and store claims on the server in fast memory or a database (key-value), where the key is the session key, the value is any data. pluses: there is full control over the authorization state (as well as the ability to end the session from the server side, and change the user's role (or other parameters) on the fly)
cons: organization interlayers - cache or storage in the database (slow), when the session service is restarted / crashed, clients will need to re-login.
one
1.1 In cookies, write either the session key or encrypted data about the user, the session is an abstract concept (it is a pair: key and data), the key must be protected, i.e. difficult to copy (at least visually difficult to remember), unique (so that there are no collisions: two different users were given the same key, i.e. it should not be a hash function from a login-password or IP or something non-unique ).
1.2 There are authorization attributes in asp.no (in which you can place checks for such a requirement, a role, a specific user), in a general sense, the logic is as follows: a request has been received to the server, then you need to look at which resource is being accessed (protected or free), if the resource is protected, then check the cookie (session key or encrypted data), decrypt / get session data from the cache and make a decision: let it in or not (give 401/403 or give 200/404/...).
1.3 Create a dictionary on the server (in the cache or database), add a check condition for the presence of an entry in the dictionary when checking the session algorithm.
1.4 With several - no need for a dictionary.
2
2.1 Even if the user logs in through VK, you still need to give your session keys / encrypted data, but inside the data you already store access_token from the VK session, so there is a very small chance that the VK token will leak, and if the session key is leaked, then the actions will be limited only by the functionality of the site.
2.2 After decrypting the cookie or data using the session key, make an additional request to the VK server with the token that was saved during authentication (access_token), the request is simple, for example, get the username, if the VK issued that the token is expired or an error, then close the session or cookies with data reset.
Very much simplified, without OOP and patterns):
Authorization:
session_start();
if (!empty($_SESSION['user_id']))
die('Вы уже авторизованы');
$user = get_user_by_login($_POST['login']);
if (!$user)
die('Пользователь не найден');
if ($_POST['pass'] !== $user['pass'])
die('Неверный пароль');
$_SESSION['user_id'] = $user['id'];
die('Привет, '.$user['login']);
session_start();
if (empty($_SESSION['user_id']))
die('Нет прав');
$user = get_user_by_id($_SESSION['user_id']);
if (!$user || !$user['active'])
{
unset($_SESSION['user_id']);
die('Нет прав');
}
session_start();
unset($_SESSION['user_id']);
if ($user['session_id'] !== session_id())
{
unset($_SESSION['user_id']);
die('Нет прав');
}
In short, the essence of authorization is that the user, instead of his password and login, receives some long, unpredictable string, which he keeps all the time of the session on his side and presents to the server for every sneeze. And except for the server, this line is given to no one.
And the server stores this line with itself, with reference to the user's record.
Additional details are the storage of this string with a time limit, tied to the IP address, browser version and other details, so that you can regulate the number of simultaneous sessions, session time, and try to detect the theft of this string. The string is usually called a hash, although not really. You can not store the string, but check it with another hash, obtained from the first one. And so on as the fantasy and perversion of thoughts grow.
From complete zero. User enters login + password:
User logs in via VK
Here you still need to very well separate the concepts of authorization and authentication.
Authentication is user definitions, that is, what kind of user it is. Usually this stage takes place immediately after entering the login password. If the login is correct, we can immediately say: "User is authenticated". For example, if you use HTTP Basic authentication, then if the login/password is incorrect, there will be a 401 error.
Authorization is a check of the user's rights to a specific resource. For example, can the user edit some material (article, comment), can he view some resource. Very often, the concept of " Firewall
" can still " emerge"." is a mechanism for determining the behavior of the authentication / authorization system. For example: In a personal account, it is necessary that the user be authorized, but on the site (docs, other pages), no. As a result, we can create two firewalls that determine this behavior for different URLs
These two mechanisms can work any way you want, the main thing is to follow some rules:
1. Do not authenticate by UserID in any case, otherwise anyone can gain access.
save only the UserID for authentication in cookies, then someone will be able to change the cookie from their side and log in as a different user. server.
3. The password in the database must be hashed, and the check must be based on hashes, and not on real passwords. Otherwise, if someone hangs your database, it is very likely that they will be able to access many other accounts, since many people use the same password.
Personally, for my projects, I always use Symfony Security , since everything in this package is already done for you. The main thing is to correctly connect and configure, and voila :)
I don't want to nerd, but the issue of protecting against fixing the session ID has not yet been addressed, in this case, the session_regenerate_id () function generates a new session ID of the current visitor. the very value of the session identifier in the cookie is set by the session_start () function, and in any case you need to call it, otherwise the sessions will not work
i.e. I want to say that trying to come up with some kind of your own solution instead of using system solutions, you risk forgetting something in the future or not taking into account due to ignorance and the need to use such a function as, for example, session_regenerate_id() , will then cause you a headache,
so in order :
1.1 What to write in cookies/session?
you do not need to write anything manually in cookies, call session_start().
you can write the value is_auth = true to the session after you check that the login and password are correct
1.2 How can I check whether the user is authorized or not on each page?
Well, this is more of an application architecture than a question of just authorization. for a couple of pages, you can make a common plug-in file for checking authorization, and for an average project, it’s better to use the framework right away, but then your questions about authorization will probably change, because. frameworks usually already have the basic functionality of authorization. in the simplest case, check that the value of the session is_auth === true
1.3 If you want the user to have only simultaneous access from one device - how to be?
Well, it's quite complicated, but I'll try to explain briefly
- firstly, you need to store the current user session ID in permanent storage, a database, or somewhere else (i.e. on each page after checking authorization, update the session ID in the database)
- secondly, you need to store authorization sessions in a specific folder specified by session_save_path($dir) function. the point is that the $dir folder should be available for you to read (read the security issue separately)
- thirdly, after successful authorization, you retrieve the session ID of this user from the database (see step 1) and delete this session from the directory (see p. 2), and only then write a new user session ID to the database (again, see 1)
1.4 And if from several?
the same as in 1.3, only earlier you had a table structure, let's say user_id, session_id, and in this case it will be user_id, session_id, device_id i.e. the meaning is that this is not a table of users, but a table of user sessions
Also I recommend reading the book "PHP. Programming Recipes" from O'Reilly, second edition or later
On the second question, in essence, nothing changes, except that it is supplemented by the initialization functionality and processing responses from vk.com. you can read about it on the page https://vk.com/dev/auth_sites
If it is still required, then in a simple and understandable form, how to create authorization on cookies is described here - habrahabr.ru/post/13726
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question