Ошибка при авторизации php

Регистрация работает отлично, данные добавляются в базу, проверки все срабатывают как надо и вопросов нет, но вот авторизация мне пишет постоянно «НЕ ВЕРНЫЙ ЛОГИН ИЛИ ПАРОЛЬ».

Переадресация на главную не происходит, сессия не создаётся и вылазит только это сообщение.

<?php
//регистрация
function checkUser($mysqli, $login, $name) {
    $stmt = $mysqli->prepare("SELECT * FROM users WHERE login=? or name=?"); 
    $stmt->bind_param("ss", $login, $name);
    $stmt->execute();
    $result = $stmt->get_result();
    return $result->fetch_assoc();
}
function regUser($mysqli, $login, $name, $pass) {
    $pass = password_hash($password, PASSWORD_DEFAULT);
    $sql = "INSERT INTO `users` (`login`, `name`, `pass`, `regdate`) VALUES(?,?,?, NOW())";
    $stmt = $mysqli->prepare($sql); 
    $stmt->bind_param("sss", $login, $name, $pass);
    $stmt->execute();
}
$errors = [];
$user = checkUser($mysqli, $_POST['login'], $_POST['name']);
if ($user && isset($_POST['enter'])) {
    if($_POST['login'] == ''){
        $errors[] = "Введите логин";
    }
    if($_POST['name'] == ''){
        $errors[] = "Введите отображаемое имя";
    }
    if($_POST['pass'] == ''){
        $errors[] = "Введите пароль";
    }
    if($_POST['passconf'] == ''){
        $errors[] = "Введите подтверждение пароля";
    }
    if ($user['login'] == $_POST['login']) {
        $errors[] = "Введённый логин уже занят";
    }
    if ($user['name'] == $_POST['name']) {
        $errors[] = "Введённое имя уже занято";
    }
}
if (!$errors) {
    regUser($mysqli, $_POST['login'], $_POST['name'], $_POST['pass']);
} else {
    $erro = '<div id="errors">'.array_shift($errors).'</div>';
}


//Скрипт авторизации
function loginUser($mysqli, $login, $name, $pass, $regdate) {
    $stmt = $mysqli->prepare("SELECT * FROM users WHERE login=? or name=? or pass=? or regdate=?");
    $pass = password_verify($_POST['pass'], $user['pass']); 
    $stmt->bind_param("ssss", $login, $name, $pass, $regdate);
    $stmt->execute();
    $result = $stmt->get_result();
    $user = $result->fetch_assoc();
}
$userlog = loginUser($mysqli, $user['login'], $user['name'], $user['pass'], $user['regdate']);
if (isset($_POST['go'])) {
    if($_POST['login'] == ''){
        $errors[] = "Вы не ввели логин";
    }
    if($_POST['pass'] == ''){
        $errors[] = "Вы не ввели пароль";
    }
    if ($user['login'] != $_POST['login']) {
        $errors[] = "Неверный логин или пароль";
    }
    if ($user['pass'] != $_POST['pass']) {
        $errors[] = "Неверный логин или пароль";
    }
}
if (!$errors && $userlog) {
        $_SESSION['USER_NAME'] = $user['name'];
        $_SESSION['USER_REGDATE'] = $user['regdate'];
        $_SESSION['USER_LOGIN_IN'] = 1;
        exit(header('Location: /'));
} else {
    $error = '<div id="errors">'.array_shift($errors).'</div>';
}

Доброго времени суток. Имею вот такую систему авторизации на сайте:

<?php
                    if(isset($_SESSION['name']))
                    {
                        echo "Какой то контент потом будет";
                    }
                    else{
                            echo '<form method="post" action="index.php">
                            <input type="text" name="login" placeholder="Логин" required/> 
                            <input type="password" name="password" placeholder="Пароль" required/>
                            <input type="submit" name="submit" value="Войти"/>
                        </form>';}
                         ?>
                                    <?php 
 
                                    if(isset($_POST[submit])){
                            $login=$_POST['login'];
                            $password=md5($_POST['password']);
 
                            $query=mysql_query("SELECT * FROM clients WHERE login='$login'");
                            $client_data = mysql_fetch_array($query);
                            if ($client_data['password'] == $password){
                                session_start();
                                $_SESSION['name']= $login;
                            }
                            else{
                                echo "Не верный логин или пароль";
                            }
                        }
                    ?>

Он нормально проверяет правильность пароль и выводит соответствующую надпись.
Но если пароль правильный, то он должен вместе формы авторизации выдать какой то контент, но вместо этого форма авторизации остается, и выходит ошибка «Warning: session_start() [function.session-start]: Cannot send session cookie» . Нагуглил лишь то, что session_start(); должен быть в начале кода, но и это не помогает. Помогите пожалуйста разобраться. И еще, впервые пишу сайт то на php с mysql.


  • Вопрос задан

    более трёх лет назад

  • 3101 просмотр

Нагуглил лишь то, что session_start(); должен быть в начале кода, но и это не помогает.

Помогает.

Вспомнил. Скорее всего, это BOM гадит.
Надо сохранять файл в кодировке UTF-8 without BOM, а лучше вообще сменить редактор на что-нибудь пристойное, с подсветкой кода хотя бы.

Пригласить эксперта

session_start() в самом начале php файла решит вашу проблему. Перед session_start не должно быть ничего в файле, кроме <?php (никаких там html тегов или ещё чего-то).

Сначала session_start, а потом уже html-код или какие-то include и всё остальное.

Вы проверяете переменную name в сессии не запустив сессиию.

if(isset($_SESSION[‘name’]))

Нужно запускать сессию до этой строчки. И вообще нужно запускать сессию до того будет произведен любой вывод данных, иначе заголовки будут уже сформированы и нельзя будет поставить куку с идентефикатором сессии. Как то так.
PS Лучше запускать сессию в самом начале выполнения скрипта

Судя по всему у вас перед выводом этого участка есть еще html, отдаваемый браузеру (Не может же у вас не быть всяких html head body и т д)

session_start();
Должен быть вообще раньше всего.

<?php $login=$_SESSION['name'];
			if(!isset($_GET["id"])){
									$id=1;
								}else
								{
									$id=$_GET["id"];
								}
								$result = mysql_query("SELECT title, zayavka, id FROM zayavki WHERE id='$id'") or die(mysql_error());
								$news = mysql_fetch_array($result);
								
						$title=mysql_result($result,0,"title"); 
						$zayavka=mysql_result($result,0,"zayavka"); 
						/* Создание формы для редактирования */ 
						print "<form method=post action='zayavki.php'>"; 
						print "<br><br><b>Введите тему:</b>"; 
						print "<br><input name='title' value='$title' size=10>"; 
						print "<br><br><b>Введите заявку:</b>"; 
						print "<br><input name='zayavka' value='$zayavka' size=10>"; 
						print "<br><br><input name='edit' type='submit' value='Сохранить'>"; 
						print "</form>"; 
															
							
				if(isset($_POST[edit])){
					$id=$_GET["id"];
					$title=$_POST['title'];
					$zayavka=$_POST['zayavka'];
					$login=$_SESSION['name'];
					$status='Открыт';
					{
					
					$query=mysql_query("UPDATE zayavki SET title = '$title', zayavka ='$zayavka' WHERE id = '$id' ") or die(mysql_error());
					}
					
						die('Ошибка');
					}
				
			?>


  • Показать ещё
    Загружается…

06 июн. 2023, в 04:00

4500 руб./за проект

06 июн. 2023, в 02:35

800 руб./в час

06 июн. 2023, в 00:15

30000 руб./за проект

Минуточку внимания

6edyuh, У вас функция login возвращает true/false от него и пляшите.

PHP
1
2
3
4
if(login()) {
    header("Location: index.php");
    die;
}

Но лучше вместо возврата true/false кидать исключение. Операции принято организовывать таким образом, что либо она исполняется полностью, либо кидает исключение. Это дает несколько плюсов.

1) Функция может что-то возвращать а не только true/false, к примеру можно разбить на 2 этапа — 2 функции. Где мы для начала распознаем пользователя, а потом уже его запоминаем

PHP
1
2
3
4
5
6
7
8
9
10
try {
    $user = auth('login', '****');
    login($user);
    $_SESSION['success'] = 'Вы успешно авторизовались';
 
    header("Location: index.php");
    die;
} catch (Exception $e) {
    $_SESSION['errors'] = $e->getMessage();
}
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function auth($login, $pass): array
{
    global $pdo;
 
    if (empty($login) || empty($pass)) {
        throw new DomainException( 'Поля логин/пароль обязательны');
    }
 
    $res = $pdo->prepare("SELECT * FROM users WHERE login = ?");
    $res->execute([$login]);
    if (!$user = $res->fetch()) {
        throw new DomainException(  'Логин/пароль введены неверно');
    }
 
    if (!password_verify($pass, $user['pass'])) {
        throw new DomainException(  'Логин/пароль введены неверно');
    }
    
    return $user;
}
PHP
1
2
3
4
5
function login($user): void
{
    $_SESSION['user']['name'] = $user['login'];
    $_SESSION['user']['id'] = $user['id'];
}

Таким образом у нас появляется возможность повторно использовать функцию login к примеру при регистрации, если вы ходите после регистрации сразу залогинить пользователя.

PHP
1
2
3
4
5
6
7
8
9
try {
    $user = registration('login', '****');
    login($user);
    
    //...
    
} catch (DomainException $e) {
    $_SESSION['errors'] = $e->getMessage();
}

2) Исключения можно выкидывать из любой вложенности вызываемых методов/функций, что избавляет от лишних проверок.

3) Ну и получается сама операция с сессией напрямую не работает. А просто возвращает пользователя либо кидает исключение. Ведь кроме передачи сообщения через сессию вы бы могли отправлять запрос через ajax и сообщение отдавать в теле ответа json-ом.

За последние 24 часа нас посетили 12276 программистов и 854 робота. Сейчас ищет 541 программист …


  1. AnonimS

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9

    Всем доброго времени суток! Сейчас пишу простенький сайт, дошел до авторизации, решил не заморачиваться, просто база с пользователями, отсылаем через ajax, обновляем страницу и записываем в переменную $_SESSION, потом сравниваем, если в сессии что-то есть выводим контект личного кабинета. Вроде все написал, проверил, все работает, на телефоне проверил, тоже работает, на другом компьютере проверил все работает, ну думаю раз на 3 машинах работает можно отсылать. Позже узнаю, что сначала 1 пользователь не может зайти, потом 2, сам проверил удаленно и действительно, не записываются данные в $_SESSION, все уже перепробовал не пишутся и все..

    Вот код, который проверяет

    1. <h2 align=»center»>Личные данные</h2>
    2. <div class=»login» align=»center»><h2>Авторизация на сайте:</h2>
    3.     <form id=»formx» method=»post» action=»»>
    4.         Логин: <input type=»text» name=»login» style=»margin-right: -1px;»><br>
    5.         Пароль: <input type=»password» name=»password»><br>
    6.         <input id=»submit» type=»submit» name=»submit» value=»Войти»>

    Вот обработчик

    1. if(isset($_POST[‘login’]) and isset($_POST[‘password’])){
    2.     if (empty($_POST[‘login’])) // Если поле логин пустое
    3.         echo ‘<div class=»red»>Поле логин не заполненно!</div>’; // То выводим сообщение об ошибке
    4.     elseif (empty($_POST[‘password’])) // Если поле пароль пустое
    5.         echo ‘<div class=»red»>Поле пароль не заполненно!</div>’; // То выводим сообщение об ошибке
    6.     else  // Иначе если все поля заполненны
    7.         $login = $_POST[‘login’]; // Присваиваем переменной значение из поля с логином            
    8.         $password = $_POST[‘password’]; // Присваиваем другой переменной значение из поля с паролем
    9.         $loginCheckDb = $con->query(«SELECT `id`, `status` FROM `users` WHERE `login` = ‘$login‘ AND `password` = ‘$password‘») or die($con->error);
    10.         $loginCheckDbROW = $loginCheckDb->fetch_assoc();
    11.         $id_db=$loginCheckDbROW[‘id’];
    12.         $status=$loginCheckDbROW[‘status’];
    13.         if (empty($id_db)) // Если запрос к бд не возвразяет id пользователя
    14.             echo ‘<div class=»red»>Неверные Логин или Пароль!</div>’; // Значит такой пользователь не существует или не верен пароль
    15.         else // Если возвращяем id пользователя, выполняем вход под ним
    16.             //$_SESSION[‘password’] = $password; // Заносим в сессию  пароль
    17.             $_SESSION[‘login’] = $login; // Заносим в сессию  логин
    18.             $_SESSION[‘id’] = $id_db; // Заносим в сессию  id
    19.             $_SESSION[‘status’] = $status;
    20.             //header(‘Location:  http://localhost/login’);
    21.             echo ‘<script>location.reload();</script>’;
    22.             echo ‘<div class=»gren»>Вы успешно вошли в систему: ‘.$_SESSION[‘login’].‘</div>’; // Выводим сообщение что пользователь авторизирован        
    23. }else echo ‘<div class=»red»>Ошибка отправки данных!</div>’;

    Вот ajax

    1. $(document).ready(function(){
    2.    $(‘#submit’).click(function(e){
    3.       var msg = $(‘#formx’).serialize();
    4.             url: ‘http://localhost/assets/php/login.php’,
    5.             success: function(data) {

    Что получается у тех, кто жалуется:
    1.Они вводят правильный логин и пароль
    2.Запрос отсылается на обработчик
    3.Возвращается строка: Вы успешно вошли в систему: Логин, который ввел пользователь
    4.Страница обновляется
    5.Проверяется условие if (isset($_SESSION[‘login’]) && isset($_SESSION[‘id’])):
    6.Выводится форма авторизации, поскольку нет переменных.

    Ткните в чем проблема может быть, я уже и <?php session_start(); ?> в разные места пробовал и в самое начало, все равно тоже самое, прям какой-то парадокс, причем скачал те же браузеры, что у них, у меня все работает, а у них нет…


  2. smitt

    С нами с:
    3 янв 2012
    Сообщения:
    3.167
    Симпатии:
    65


  3. AnonimS

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9

    Да, в логах ни чего не нашел..
    access

    1. IP — — [26/Feb/2017:22:36:50 +0300] «GET /assets/image/icon-2.svg HTTP/1.1» 304 180 «http://host.ru/assets/css/style.css» «Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 YaBrowser/17.3.0.1785 Yowser/2.5 Safari/537.36»
    2. IP — — [26/Feb/2017:22:36:50 +0300] «GET /assets/image/icon-3.svg HTTP/1.1» 304 181 «http://host.ru/assets/css/style.css» «Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 YaBrowser/17.3.0.1785 Yowser/2.5 Safari/537.36»
    3. IP — — [26/Feb/2017:22:36:50 +0300] «GET /assets/image/icon-4.svg HTTP/1.1» 304 181 «http://host.ru/assets/css/style.css» «Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 YaBrowser/17.3.0.1785 Yowser/2.5 Safari/537.36»
    4. IP — — [26/Feb/2017:22:36:50 +0300] «GET /assets/image/icon-5.svg HTTP/1.1» 304 180 «http://host.ru/assets/css/style.css» «Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 YaBrowser/17.3.0.1785 Yowser/2.5 Safari/537.36»
    5. IP — — [26/Feb/2017:22:36:50 +0300] «GET /assets/image/bg.gif HTTP/1.1» 304 180 «http://host.ru/assets/css/style.css» «Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 YaBrowser/17.3.0.1785 Yowser/2.5 Safari/537.36»
    6. 127.0.0.1 — — [26/Feb/2017:22:36:59 +0300] «OPTIONS * HTTP/1.0» 200 126 «-» «Apache/2.4.10 (Debian) (internal dummy connection)»
    7. IP — — [26/Feb/2017:22:44:07 +0300] «POST /login HTTP/1.1» 200 3496 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 YaBrowser/17.3.0.1785 Yowser/2.5 Safari/537.36»
    8. IP — — [26/Feb/2017:22:44:07 +0300] «GET /assets/css/bootstrap.min.css.map HTTP/1.1» 200 3172 «-» «Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 YaBrowser/17.3.0.1785 Yowser/2.5 Safari/537.36»
    9. IP — — [26/Feb/2017:22:44:27 +0300] «GET /login HTTP/1.1» 200 3727 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    10. IP — — [26/Feb/2017:22:44:54 +0300] «GET /login HTTP/1.1» 200 3727 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    11. IP — — [26/Feb/2017:22:44:55 +0300] «GET /assets/image/fav.png HTTP/1.1» 200 1211 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    12. IP — — [26/Feb/2017:22:45:02 +0300] «GET /login HTTP/1.1» 200 3727 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    13. IP — — [26/Feb/2017:22:45:05 +0300] «GET /login HTTP/1.1» 200 3726 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    14. IP — — [26/Feb/2017:22:45:06 +0300] «POST /assets/php/content.php HTTP/1.1» 200 782 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    15. IP — — [26/Feb/2017:22:45:20 +0300] «POST /assets/php/content.php HTTP/1.1» 200 1025 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    16. IP — — [26/Feb/2017:22:45:24 +0300] «POST /assets/php/content.php HTTP/1.1» 200 849 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    17. IP — — [26/Feb/2017:22:45:26 +0300] «POST /assets/php/content.php HTTP/1.1» 200 1299 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    18. IP — — [26/Feb/2017:22:45:27 +0300] «POST /assets/php/content.php HTTP/1.1» 200 1371 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    19. IP — — [26/Feb/2017:22:45:28 +0300] «POST /assets/php/content.php HTTP/1.1» 200 839 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    20. IP — — [26/Feb/2017:22:45:30 +0300] «POST /assets/php/content.php HTTP/1.1» 200 1124 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    21. IP — — [26/Feb/2017:22:45:30 +0300] «POST /assets/php/content.php HTTP/1.1» 200 1170 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    22. IP — — [26/Feb/2017:22:45:31 +0300] «POST /assets/php/content.php HTTP/1.1» 200 846 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    23. IP — — [26/Feb/2017:22:45:32 +0300] «POST /assets/php/content.php HTTP/1.1» 200 1019 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    24. IP — — [26/Feb/2017:22:45:33 +0300] «POST /assets/php/content.php HTTP/1.1» 200 1034 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    25. IP — — [26/Feb/2017:22:45:34 +0300] «POST /assets/php/content.php HTTP/1.1» 200 991 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    26. IP — — [26/Feb/2017:22:45:35 +0300] «POST /assets/php/content.php HTTP/1.1» 200 936 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    27. IP — — [26/Feb/2017:22:45:36 +0300] «POST /assets/php/content.php HTTP/1.1» 200 957 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    28. IP — — [26/Feb/2017:22:45:37 +0300] «POST /assets/php/content.php HTTP/1.1» 200 837 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    29. IP — — [26/Feb/2017:22:45:38 +0300] «POST /assets/php/content.php HTTP/1.1» 200 864 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    30. IP — — [26/Feb/2017:22:45:59 +0300] «POST /assets/php/content.php HTTP/1.1» 200 746 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    31. IP — — [26/Feb/2017:22:46:01 +0300] «POST /assets/php/content.php HTTP/1.1» 200 923 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»
    32. IP — — [26/Feb/2017:22:46:03 +0300] «GET / HTTP/1.1» 200 4503 «http://host.ru/login» «Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04»

    error(Последние ошибки, это я поставил session.auto_start = 1 и поменял директорию хранения сессий, может это поможет)

    1. [Sun Feb 26 22:16:17.610203 2017] [mpm_prefork:notice] [pid 1071] AH00171: Graceful restart requested, doing restart
    2. [Sun Feb 26 22:16:17.658400 2017] [alias:warn] [pid 1071] AH00671: The Alias directive in /etc/apache2/conf-enabled/phpmyadmin.conf at line 3 will probably never match because it overlaps an earlier Alias.
    3. [Sun Feb 26 22:16:17.683134 2017] [mpm_prefork:notice] [pid 1071] AH00163: Apache/2.4.10 (Debian) configured — resuming normal operations
    4. [Sun Feb 26 22:16:17.683160 2017] [core:notice] [pid 1071] AH00094: Command line: ‘/usr/sbin/apache2’
    5. [Sun Feb 26 22:16:32.451864 2017] [:error] [pid 3894] [client IP:26450] PHP Notice:  A session had already been started — ignoring session_start() in /var/www/html/assets/php/login.php on line 27, referer: http://host.ru/login
    6. [Sun Feb 26 22:21:48.177831 2017] [:error] [pid 3897] [client IP:26273] PHP Notice:  A session had already been started — ignoring session_start() in /var/www/html/assets/php/login.php on line 27, referer: http://host.ru/login
    7. [Sun Feb 26 22:29:35.590111 2017] [:error] [pid 3894] [client IP:26328] PHP Notice:  A session had already been started — ignoring session_start() in /var/www/html/pages/logout.php on line 3, referer: http://host.ru/login
    8. [Sun Feb 26 22:30:11.429577 2017] [:error] [pid 3894] [client IP:26340] PHP Notice:  A session had already been started — ignoring session_start() in /var/www/html/pages/login.php on line 6, referer: http://host.ru/login
    9. [Sun Feb 26 22:45:06.649209 2017] [:error] [pid 3896] [client IP:26470] PHP Notice:  A session had already been started — ignoring session_start() in /var/www/html/pages/content/login/kab_1.php on line 2, referer: http://host.ru/login
    10. [Sun Feb 26 22:45:20.239022 2017] [:error] [pid 3895] [client IP:26472] PHP Notice:  A session had already been started — ignoring session_start() in /var/www/html/pages/content/login/kab_3.php on line 19, referer: http://host.ru/login
    11. [Sun Feb 26 22:45:38.818821 2017] [:error] [pid 3895] [client IP:26472] PHP Notice:  A session had already been started — ignoring session_start() in /var/www/html/pages/content/login/za_form.php on line 13, referer: http://host.ru/login


  4. smitt

    С нами с:
    3 янв 2012
    Сообщения:
    3.167
    Симпатии:
    65

    как думаешь?)
    — Добавлено —
    избавься от ошибок дальше будем смотреть.
    А сфига менять директорию?
    Может туда прав нет…
    Проверяй, ответы у тебя в логах)


  5. TeslaFeo

    С нами с:
    9 мар 2016
    Сообщения:
    2.995
    Симпатии:
    759

    1. session_start(); в обработчик в самое начало.
    2. пароль в сессии хранить не нужно
    3. полученные от пользователя строки нужно проверять хотя бы стандартными функциями


  6. AnonimS

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9

    права дал, от ошибок , да надо избавляться. А не может к примеру блокировать антивирус падения файлика куки?
    — Добавлено —

    Хорошо, попробую с этого начать.


  7. AnonimS

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9

    Хотя кука падает-то клиентам, в браузере и у себя и пользователя я ее вижу, но получается у меня он находит значения по ид куки, а у пользователя нет, завтра сравню, есть ли вообще на сервере эта кука со значениями, если ее нет, то проблема в том, что куда кидать ее на сервере…


  8. AnonimS

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9

    Все ошибки устранил, но проблема не ушла, но я нашел причину. Что у нас получается:
    1.Загружаю страничку с формой, стартует сессия, кидается кука на комп клиента с ID сессии и на сервер в папку session.save_path(Кстати какие у нее должны быть права, я пока поставил 777, ну это не правильно, каждый может зайти и поменять данные?) с таким же ID, все хорошо пока..
    2.Ввожу логин и пароль, нажимаю войти, стартует новая сессия с ID_2, переменные пишутся в нее в div выводиться, что все хорошо, пользователь зашел, страница обновляется и опять форма авторизации, потому что ID сессии нет переменных.
    Вопрос. Почему такое может быть? У меня 2 варианта:
    1.Надо проверять есть ли кука с ID сессии, но тогда выдается ошибка в логах, что Undefined variable: _SESSION
    2.Это настройки php.ini (возможно надо настроить время жизни сессии)
    Вот они

    1. session.save_handler = files
    2. session.save_path = «/var/www/html/temp»
    3. session.use_strict_mode = 0
    4. session.use_only_cookies = 1
    5. session.cookie_lifetime = 0
    6. session.cookie_httponly =
    7. session.serialize_handler = php
    8. session.gc_probability = 0
    9. session.gc_divisor = 1000
    10. session.gc_maxlifetime = 1440
    11. ;session.entropy_length = 32
    12. ;session.entropy_file = /dev/urandom
    13. session.cache_limiter = nocache
    14. session.cache_expire = 180
    15. session.use_trans_sid = 0
    16. session.hash_function = 0
    17. session.hash_bits_per_character = 5
    18. ame=src,input=src,form=fakeentry«
    19. url_rewriter.tags = «a=href,area=href,frame=src,input=src,form=fakeentry«
    20. ;session.upload_progress.enabled = On
    21. ;session.upload_progress.cleanup = On
    22. ;session.upload_progress.prefix = «upload_progress_«
    23. ;session.upload_progress.name = «PHP_SESSION_UPLOAD_PROGRESS«
    24. ;session.upload_progress.freq =  «1%«
    25. ;session.upload_progress.min_freq = «1«

    Ткните, что не так делаю, уже перечитал про сессии мануал, там есть что-то про механизм задваивания, но у меня там не та ситуация. Есть и про навигацию JS, ведь у меня контект подгружается динамически, соответственно там написано, что надо слать заголовки, думаю с этого дальше начну..
    Так же заметил в логах такую ошибку internal dummy connection, так и не нашел что она значит, может кто подскажет?


  9. TeslaFeo

    С нами с:
    9 мар 2016
    Сообщения:
    2.995
    Симпатии:
    759

    сессии по умолчанию нормально должны работать.
    не надо лазить в настройки если не знаешь что делаешь и зачем тебе это нужно.
    верни всё как было.


  10. AnonimS

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9

    Понял, я поменял только путь, ну сейчас все по умолчанию вернул. Все равно задваивается..
    — Добавлено —
    Вот к примеру, я нажимаю войти, ajax’ом посылаю запрос, там создается куки, но они не посылаются пользователю, вот в чем проблема, думаю надо в эту сторону копать..


  11. Sergey_Tsarev

    Sergey_Tsarev
    Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105

    А для чего у тебя первая сессия стартует? Какую информацию она содержит?


  12. AnonimS

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9

    Вроде решил проблему, путем удаления ajax’а, просто форма и action на обработчик..

    Она стартует, чтобы взять от туда переменные и проверить такого пользователя на его данные из базы. Я может не понимаю алгоритм, удали ajax и все заработало, куки пишуться именно в сессию, которая уже есть.


  13. Sergey_Tsarev

    Sergey_Tsarev
    Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105

    Мне кажется, что это можно сделать проще. Пользователь ввёл логин и пароль и нажал кнопку «Войти», например. Ты в принимающем скрипте проверяешь есть ли такой пользователь и если есть, верный ли пароль он указал. Если все верно, то стартуешь сессию и в неё записываешь ID юзера и допустим строку сгенерированную из случайных символов. И создаёшь куки с теми же данными. Потом сравниваешь данные из куки с данными из сессии и если они одинаковые, значит пользователь авторизован для доступа в личный кабинет, например. В противном случае выкидываешь пользователя на страницу входа.

Система авторизации с помощью cookie на PHP

loader

В прошлом уроке мы изучили механизм взаимодействия с cookie в языке PHP.

Теперь давайте попробуем применить эти знания на практике — создадим простейшую систему авторизации с использованием этих самых cookie. Ведь для авторизации нам просто необходимо при каждом запросе идентифицировать пользователя — сохранив специальное значение в куки этого легко добиться!

Техническое задание

Начнём мы это дело с описания будущей системы. Пусть у нас будут следующие компоненты:

  1. Главная страница сайта с каким-либо содержимым. Вверху страницы выводится:
    • если пользователь авторизован: Добро пожаловать, %username%.
    • если пользователь неавторизован: Авторизация — слово является ссылкой, которая ведёт на форму авторизации.
      Авторизован пользователь или нет, определяется с помощью cookie.
  2. Страница с формой авторизации. Два инпута для логина и пароля и кнопкой «Вход». Если введены правильные логин и пароль, устанавливаются cookie со значениями переданных данных, а затем пользователя автоматически редиректит (перенаправляет) на главную страницу.
  3. Страница для разлогинивания — при переходе на неё cookie будут удаляться из браузера пользователя, а затем выполняется редирект на главную страницу.

Решение

Продумываем архитектуру

Первое, о чём нам нужно подумать — это то, как будут храниться элементы этой системы, и сколько их вообще будет.

Начнем с простого — для начала у нас должно получиться 3 странички, которые мы описали в ТЗ.

Ещё нам потребуется функционал, который будет проверять, авторизован ли пользователь. Если мы перечитаем ТЗ, то поймём, что он используется в двух местах — и на главной странице и на странице авторизации. Значит, стоит вынести этот механизм в отдельный файл, и использовать его в двух местах сразу.

Ну и наконец, нам где-то нужно хранить самих пользователей, а именно — их логины и пароли. Создадим для этого простенькую «базу данных» — массив, с набором пар логин-пароль. Это ещё один файл.

Пишем код

Все исходники по данному заданию доступны здесь.

База данных

Ну вот, всё продумали, осталось только написать. Предлагаю начать с нашей базы данных. Создадим файл usersDB.php и запишем в него несколько пользователей.

<?php
return [
    ['login' => 'admin', 'password' => '[email protected]'],
    ['login' => 'moderator', 'password' => 'password'],
    ['login' => 'user', 'password' => '123'],
];

Функции проверки авторизации

Давайте теперь напишем функцию, которая будет проверять, являются ли переданные в неё логин и пароль правильными. Для этого создадим ещё один файл auth.php. В нём нам для получения списка пользователей потребуется подключить файл с базой данных.

<?php
function checkAuth(string $login, string $password): bool 
{
    $users = require __DIR__ . '/usersDB.php';

    foreach ($users as $user) {
        if ($user['login'] === $login 
            && $user['password'] === $password
        ) {
            return true;
        }
    }

    return false;
}

В цикле мы пробегаемся по базе данных пользователей и пытаемся найти пользователя с переданными логином и паролем. Если такой пользователь в массиве найден — возвращаем true. Иначе — false.

Давайте теперь ещё напишем функцию, которая будет возвращать логин текущего пользователя. Эта функция будет проверять текущие значения cookie с ключами login и password с помощью уже существующей функции checkAuth. При этом если пользователь найдётся, то она вернёт его login, а иначе — null. Назовём эту нашу новую функцию getUserLogin.

//продолжение файла auth.php

function getUserLogin(): ?string
{
    $loginFromCookie = $_COOKIE['login'] ?? '';
    $passwordFromCookie = $_COOKIE['password'] ?? '';

    if (checkAuth($loginFromCookie, $passwordFromCookie)) {
        return $loginFromCookie;
    }

    return null;
}

На этом всю логику проверки логина мы описали. Теперь займёмся непосредственно страничками.

Главная страница

Создадим файл index.php. Для простоты примера мы будем использовать только строку с приветствием авторизованного пользователя, либо ссылкой на авторизацию. В этой странице нам потребуется функция проверки авторизации через cookie, поэтому здесь нужно подключить файл auth.php.

<?php
require __DIR__ . '/auth.php';
$login = getUserLogin();
?>
<html>
<head>
    <title>Главная страница</title>
</head>
<body>
<?php if ($login === null): ?>
<a href="/login.php">Авторизуйтесь</a>
<?php else: ?>
Добро пожаловать, <?= $login ?>
<br>
<a href="/logout.php">Выйти</a>
<?php endif; ?>
</body>
</html>

Наша главная страничка готова. Можно зайти на неё и убедиться, что мы не авторизованы.

Главная страничка с призывом авторизации

Форма авторизации

Давайте теперь сделаем форму авторизации — создаём файл login.php и для начала набрасываем саму HTML-форму. Шаблон получился следующим.

<html>
<head>
    <title>Форма авторизации</title>
</head>
<body>
<form action="/login.php" method="post">
    <label for="login">Имя пользователя: </label><input type="text" name="login" id="login">
    <br>
    <label for="password">Пароль: </label><input type="password" name="password" id="password">
    <br>
    <input type="submit" value="Войти">
</form>
</body>
</html>

Давайте теперь добавим логику проверки переданных данных.

<?php
if (!empty($_POST)) {
    require __DIR__ . '/auth.php';

    $login = $_POST['login'] ?? '';
    $password = $_POST['password'] ?? '';

    if (checkAuth($login, $password)) {
        setcookie('login', $login, 0, '/');
        setcookie('password', $password, 0, '/');
        header('Location: /index.php');
    } else {
        $error = 'Ошибка авторизации';
    }
}
?>
<html>
<head>
    <title>Форма авторизации</title>
</head>
<body>
<?php if (isset($error)): ?>
<span style="color: red;">
    <?= $error ?>
</span>
<?php endif; ?>
<form action="/login.php" method="post">
    <label for="login">Имя пользователя: </label><input type="text" name="login" id="login">
    <br>
    <label for="password">Пароль: </label><input type="password" name="password" id="password">
    <br>
    <input type="submit" value="Войти">
</form>
</body>
</html>

Логика простейшая — если был отправлен POST-запрос, проверяем правильные ли логин и пароль были переданы.

Если нет — то создаём переменную $error, в которой пишем об ошибке авторизации. Позже в шаблоне выводим эту ошибку, если эта переменная объявлена.

Если же авторизация прошла успешно, мы устанавливаем cookie с ключами login и password, в которые помещаем значения из POST-запроса. После этого выполняем редирект на главную страницу.

Редирект делается с помощью заголовка в HTTP-ответе. Этот заголовок называется Location и выглядит следующим образом:

Location: адрес_на_который_нужно_перейти

Для формирования заголовков в PHP используется функция header – ознакомиться с ней более детально вы можете здесь.

Теперь можно попробовать нашу страничку в действии. Давайте для начала введём несуществующую пару логина и пароля. Например, 123:123.

Ошибка при авторизации

Мы увидим соответствующую ошибку.

Теперь давайте зайдем под пользователем user. В нашей БД для него указан пароль 123. Пробуем…

Успешная авторизация

Успех! Нас автоматически перекинуло на главную страницу, где мы видим приветствие для данного пользователя!

Безопасная система авторизации

Однако, данная схема имеет недостаток — пароль используется в открытом виде, а это небезопасно. Всё что идёт дальше — только для ознакомления, пока это слишком сложно реализовать без хорошей архитектуры и полноценной базы данных.

Хеширование паролей

В более совершенных системах авторизации используют хеш от пароля.

Если по-простому, то это такое вычисленное значение, полученное в результате выполнения над паролем определенных манипуляций. В результате этих действий мы получаем строку, из которой нельзя восстановить исходный пароль.

Но мы можем снова повторить над паролем те же действия и сравнить получившиеся значения. То есть сравниваются хеши, а не исходные пароли. И в базе данных тоже хранят хеши, а после того как от клиента пришел пароль в открытом виде, вычисляют его хэш и сравнивают со значением в базе. Если они равны — значит от пользователя пришел верный пароль.

Для чего это делается? Да просто потому, что если сайт будет каким-то образом взломан, то злоумышленник в базе данных не найдёт паролей в открытом виде — только хеши. А так как из хеша получить пароль довольно сложно (при условии, что хеш-функция надежна и используется надёжный пароль), то пароль он не узнает. Следовательно:

  1. злоумышленник не сможет использовать пароль для входа на взломанный сайт;
  2. он также не сможет использовать этот пароль для входа под тем же логином и паролем в другие места (ведь довольно часто люди используют одинаковые пароли для всего).

Вычисляются хеши с помощью хеш-функции. Хеш-функции при этом вычисляют хеши следуя алгоритмам хеширования. Сейчас в PHP для хеширования следует использовать функцию password_hash(), а для проверки хеша — password_verify(). Если вы в каком-то уроке увидите, что для хеширования паролей используется md5 — бегите оттуда, такие хеши вскрываются за несколько минут, она устарела ещё лет 10 назад.

Авторизационные токены

Помимо хеша пароля в базе данных так же принято хранить так называемые авторизационные токены (AuthToken). Это комбинация символов (желательно подлиннее и с кучей кракозябр), которая генерируется при успешной авторизации пользователя и сохраняется в базе данных. А ещё она и пользователю отправляется.

И потом пользователь с помощью cookie передает этот токен на сервер, где он сравнивается со значением в базе данных. Если они равны, то считаем пользователя авторизованным. Для чего? Дело в том, что куки могут быть похищены злоумышленниками (очень многими способами, не будем об этом в этой статье, кому интересно — погуглите). И если злоумышленнику попадет в руки токен — он не сможет получить исходный пароль. О том, почему это так важно, я уже объяснил.

Заключение

Повторюсь, два последних параграфа здесь только для ознакомления. Реализуем мы их в дальнейших уроках, когда будем знать чуть больше вещей. Пока что — вот такая простейшая, но небезопасная система авторизации.

Ах да, чуть не забыл, все исходники к каждому уроку я для вашего удобства буду выкладывать на github – вот тут.

loader

loader

Понравилась статья? Поделить с друзьями:

Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • Ошибка при авторизации epic games
  • Ошибка при авторизации bluestacks
  • Ошибка при автозапуске oc7
  • Ошибка при vlookup

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии