P
P
particle_accelerator2015-08-30 02:12:40
PHP
particle_accelerator, 2015-08-30 02:12:40

Http authentication is not working correctly, why?

I want to make an entrance to the site with a password for users who have username and password in the database. There is a code for this:

<?php
            require_once('shared_php/connect_vars.php');
            require_once('shared_php/app_vars.php');
            
            header('HTTP/1.1 401 Unauthorized');
            header('WWW-Authenticate:Basic realm="entering"');
            exit ("<h3>Неверное имя пользователя или пароль. Попробуйте еще раз.</h3>");
            // Если была нажата "Отмена"
        
            $username=mysqli_real_escape_string($connect, trim($_SERVER['PHP_AUTH_USER']));
            $password=mysqli_real_escape_string($connect, trim($_SERVER['PHP_AUTH_PW']));
            $connect=mysqli_connect(DM_HOST, DB_USER, DB_PASSWORD, DB_NAME);
            //Проверка логина и пароля
            $check_password="SELECT user_id, username FROM signups WHERE username='$username' AND password=SHA('$password')"; //Выберутся все такие username; В идеале - одна строка
            //с логином, паролем и другой инфой (ненужной) в ней
            $query=mysqli_query($connect, $check_password);
            
            if (mysqli_num_rows($query)==1) {
                //все норм
                $row=mysqli_fetch_array($query);
                $user_id=$row['user_id'];
                $username=$row['username'];
            }

However, when I enter the correct login and password, which are definitely in the database, the else block is executed (the login and password entry form appears again).
In addition, if you just separately put something like this on some page:
<?php
    $username='pet';
    $password='rocks';
    if  (($_SERVER['PHP_AUTH_USER']!=$username) OR ($_SERVER['PHP_AUTH_PW']!=$password)) {
        // Что-то не так
        header('HTTP/1.1 401 Unauthorized');
        header('WWW-Authenticate:Basic realm="petrocks"');
        
        exit ("<h3>Неверное имя пользователя или пароль. Попробуйте еще раз.</h3>");
    // Если была нажата "Отмена"
    }
?>

Then the first time it enters normally (when entering the correct data), but if after that you change the login / password in the script, then after refreshing the page and entering new correct data, an error occurs (reloads the form again), and so on until the script does not return the old login and password and then do not enter them into the form (after that it loads the desired page).

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Maxim Khan-Magomedov, 2015-09-03
@ozgg

I think the problem is that in the first case you are sending a 401 status every time, regardless of whether the user has already entered the correct data or not. Try wrapping it into something like:

$authenticated = false;
if (isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) {
  // ищем пользователя в базе
  // выставляем $authenticated в true/false в зависимости от того, нашёлся ли пользователь.
}

if ($authenticated) {
  // показываем страницу аутентифицированному пользователю
} else {
  header('HTTP/1.1 401 Unauthorized');
  header('WWW-Authenticate:Basic realm="petrocks"');

  echo 'Представься, мразь', PHP_EOL;
}

S
Stac, 2015-09-03
@Stac

In addition to ozgg 's answer :
1) Don't forget to implement logout (logout) with such authorization, otherwise you will soon have to write the second question here
:) there is no easy way to force the browser to stop sending you a username and password with each request, then the logout fact must be implemented on your own.
And take this into account when logging in. Those. you need to add a condition to search for a user in the database - not only check for the presence of $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], but also check your variable that stores the sign that the user is logged out
2) Be careful with trim. If you don't allow spaces in your username and password, why are they only removed from the ends?
3) If the "Cancel" button was pressed, it is better to redirect to some relevant page (for example, the main one). This is from experience with clients.
4) Instead of "HTTP/1.1 401 Unauthorized" header, it's better to use "Status: 401 Unauthorized". Also from experience. Experience in deploying to a Windows server.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question