Разное

Php авторизация с помощью сессий – . PHP

Авторизация на сессиях PHP и MySQL -Будни программиста


Итак, как я и обещал, сегодня я расскажу как сделать свою авторизацию используя session, php и mysql. Для начала определимся что такое сессия и чем она отличается от cookie.
Session – это механизм, позволяющий однозначно идентифицировать браузер и создающий для этого браузера файл на сервере, в котором хранятся переменные сеанса.
Cookies — это механизм хранения данных броузером удаленного компьютера для идентификации возвращающихся посетителей и хранения параметров веб-страниц.
Т.е. главное различие это место хранения данных, у сессий на стороне сервера, у куков на стороне клиента, это различие критично. Если украсть у пользователя cookie довольно просто то с сессиями не все так просто. Ну а теперь перейдем к практической части а именно к написанию своей авторизации.
Для начала определим имена файлов:

  • config.php — хранит данные для подключения к Базе Данных ( далее БД )
  • functions.php — содержит в себе все функции для работы авторизации
  • join.php — простейший пример регистрации пользователя в системе
  • login.php — служит для входа в систему
  • logout.php — служит для выхода из системы
  • members.php — служит для проверки авторизации ( простейший пример «закрытой» части сайта

Для начала создадим БД и таблицу где будут храниться данные пользователей.

SQL дамп таблицы пользователей

1
2
3
4
5
6

CREATE TABLE users (
  id INT(5) NOT NULL AUTO_INCREMENT,
  login VARCHAR(15) DEFAULT ‘0’ ,
  password VARCHAR(15) DEFAULT ‘0’ ,
  PRIMARY KEY (id)
);

config.php

Что содержит данный файл я уже говорил, поэтому просто приведу его код.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<?php
# Запуск сессии
session_start();
# Служит для отладки, показывает все ошибки, предупреждения и т.д.
error_reporting(E_ALL);
# Подключение файлов с функциями
include_once(«functions.php»);
# В этом массиве далее мы будем хранить сообщения системы, т.е. ошибки.
$messages=array();
# Данные для подключения к БД
$dbhost=»localhost»;
$dbuser=»database_user»;
$dbpass=»user_password»;
$dbname=»datebase»;
# Вызываем функцию подключения к БД
connectToDB();
?>

functions.php

Самый большой файл из всех в данной статье, содержит все функции. Приведу исходный код а потом прокомментирую каждую функцию.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

<?php

function connectToDB() {
  global $link, $dbhost, $dbuser, $dbpass, $dbname;
  ($link = mysql_pconnect(«$dbhost», «$dbuser», «$dbpass»)) || die(«Couldn’t connect to MySQL»);

  mysql_select_db(«$dbname», $link) || die(«Couldn’t open db: $dbname. Error if any was: «.mysql_error() );
}

function newUser($login, $password) {
  global $link;

  $query=»INSERT INTO users (login, password) VALUES(‘$login’, ‘$password’)»;
  $result=mysql_query($query, $link) or die(«Died inserting login info into db.  Error returned if any: «.mysql_error());

  return true;
}

function displayErrors($messages) {
  print(«<b>Возникли следующие ошибки:</b>\n<ul>\n»);

  foreach($messages as $msg){
    print(«<li>$msg</li>\n»);
  }
  print(«</ul>\n»);
}

function checkLoggedIn($status){
  switch($status){
    case «yes»:
      if(!isset($_SESSION[«loggedIn»])){
        header(«Location: login.php»);
        exit;
      }
      break;

    case «no»:
      if(isset($_SESSION[«loggedIn»]) && $_SESSION[«loggedIn»] === true ){
        header(«Location: members.php»);
      }
      break;
  }
  return true;
}

function checkPass($login, $password) {
  global $link;

  $query=»SELECT login, password FROM users WHERE login=’$login’ and password=’$password'»;
  $result=mysql_query($query, $link)
    or die(«checkPass fatal error: «.mysql_error());

  if(mysql_num_rows($result)==1) {
    $row=mysql_fetch_array($result);
    return $row;
  }
  return false;
}

function cleanMemberSession($login, $password) {
  $_SESSION[«login»]=$login;
  $_SESSION[«password»]=$password;
  $_SESSION[«loggedIn»]=true;
}

function flushMemberSession() {
  unset($_SESSION[«login»]);
  unset($_SESSION[«password»]);
  unset($_SESSION[«loggedIn»]);
  session_destroy();
  return true;
}

function field_validator($field_descr, $field_data, $field_type, $min_length=»», $max_length=»», $field_required=1) {

  global $messages;

  if(!$field_data && !$field_required){ return; }

  $field_ok=false;

  $email_regexp=»^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|»;
  $email_regexp.=»(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$»;

  $data_types=array(
    «email»=>$email_regexp,
    «digit»=>»^[0-9]$»,
    «number»=>»^[0-9]+$»,
    «alpha»=>»^[a-zA-Z]+$»,
    «alpha_space»=>»^[a-zA-Z ]+$»,
    «alphanumeric»=>»^[a-zA-Z0-9]+$»,
    «alphanumeric_space»=>»^[a-zA-Z0-9 ]+$»,
    «string»=>»»
  );

  if ($field_required && empty($field_data)) {
    $messages[] = «Поле $field_descr является обезательным»;
    return;
  }

  if ($field_type == «string») {
    $field_ok = true;
  } else {
    $field_ok = ereg($data_types[$field_type], $field_data);
  }

  if (!$field_ok) {
    $messages[] = «Пожалуйста введите нормальный $field_descr.»;
    return;
  }

  if ($field_ok && ($min_length > 0)) {
    if (strlen($field_data) < $min_length) {
      $messages[] = «$field_descr должен быть не короче $min_length символов.»;
      return;
    }
  }

  if ($field_ok && ($max_length > 0)) {
    if (strlen($field_data) > $max_length) {
      $messages[] = «$field_descr не должен быть длиннее $max_length символов.»;
      return;
    }
  }
}
?>

А теперь по порядку

  • function connectToDB() — служит для подключения к базе данных
  • function newUser($login, $password) — служит для создания нового пользователя в системе
  • function displayErrors($messages) — выводит массив ошибок
  • function checkLoggedIn($status) — проверяет авторизацию пользователя.
  • function checkPass($login, $password) — проверяет пользователя по БД во время авторизации
  • function cleanMemberSession($login, $password) — авторизует пользователя
  • function flushMemberSession() — выход, или если вам будет удобнее logout
  • function field_validator($field_descr, $field_data, $field_type, $min_length=»», $max_length=»», $field_required=1) — Валидатор данных, проверяет соответствие полей требованиям системы

Работу каждой функции я описывать не буду, т.к. они довольно простые, в данный момент нас интересует только логика. Если будут вопросы — спрашивайте.

join.php

Итак исходник:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

<?php
include_once(«config.php»);

checkLoggedIn(«no»);

$title=»страница регистрации»;

if(isset($_POST[«submit»])){
  field_validator(«login name», $_POST[«login»], «alphanumeric», 4, 15);
  field_validator(«password», $_POST[«password»], «string», 4, 15);
  field_validator(«confirmation password», $_POST[«password2»], «string», 4, 15);

  if(strcmp($_POST[«password»], $_POST[«password2»])) {

    $messages[]=»Ваши пароли не совпадают»;
  }
 
  $query=»SELECT login FROM users WHERE login='».$_POST[«login»].»‘»;

  $result=mysql_query($query, $link) or die(«MySQL query $query failed.  Error if any: «.mysql_error());

  if( ($row=mysql_fetch_array($result)) ){
    $messages[]=»Логин \»».$_POST[«login»].»\» уже занят, попробуйте другой.»;
  }

  if(empty($messages)) {
    newUser($_POST[«login»], $_POST[«password»]);

    cleanMemberSession($_POST[«login»], $_POST[«password»]);

    header(«Location: members.php»);

  }
}
?>
<html>
<head>
<title><?php print $title; ?></title>
<meta http-equiv=»Content-Type» content=»text/html; charset=uft-8″>
</head>
<body>
<h2><?php print $title; ?></h2>
<?php
if(!empty($messages)){
  displayErrors($messages);
}
?>
<form action=»<?php print $_SERVER[«PHP_SELF»]; ?>» method=»POST»>
<table>
<tr><td>Логин:</td><td><input type=»text» name=»login»
value=»<?php print isset($_POST[«login»]) ? $_POST[«login»] : «» ; ?>»
maxlength=»15″></td></tr>
<tr><td>Пароль:</td><td><input type=»password» name=»password» value=»» maxlength=»15″></td></tr>
<tr><td>Повторить пароль:</td><td><input type=»password» name=»password2″ value=»» maxlength=»15″></td></tr>
<tr><td>&nbsp;</td><td><input name=»submit» type=»submit» value=»Submit»></td></tr>
</table>
</form>
</body>
</html>

Если кратко описать работу скрипта получится что то вроде:
1. Если уже авторизованы пересылаем на members.php ( строка 4 )
2. Если существует $_POST[‘submit’] ( если отправили данные с формы ) проверяем поля валидатором, проверяем наличие такого пользователя, если никаких ошибок нет, добавляем нового пользователя, ставим сессию и пускаем на members.php
3. Если есть ошибки — выводим
4. Выводим форму

login.php

Код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

<?php
include_once(«config.php»);

checkLoggedIn(«no»);

$title=»Страница авторизации»;

if(isset($_POST[«submit»])) {
  field_validator(«login name», $_POST[«login»], «alphanumeric», 4, 15);
  field_validator(«password», $_POST[«password»], «string», 4, 15);
  if($messages){
    doIndex();
    exit;
  }

    if( !($row = checkPass($_POST[«login»], $_POST[«password»])) ) {
        $messages[]=»Incorrect login/password, try again»;
    }

  if($messages){
    doIndex();
    exit;
  }

  cleanMemberSession($row[«login»], $row[«password»]);

  header(«Location: members.php»);
} else {
  doIndex();
}

function doIndex() {
  global $messages;
  global $title;
?>
<html>
<head>
<title><?php print $title; ?></title>
<meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″>
</head>
<body>
<h2><?php print $title; ?></h2>
<?php
if($messages) { displayErrors($messages); }
?>
<form action=»<?php print $_SERVER[«PHP_SELF»]; ?>» method=»POST»>

<table>
<tr><td>Логин:</td><td><input type=»text» name=»login»
value=»<?php print isset($_POST[«login»]) ? $_POST[«login»] : «» ; ?>»
maxlength=»15″></td></tr>
<tr><td>Пароль:</td><td><input type=»password» name=»password» value=»» maxlength=»15″></td></tr>
<tr><td>&nbsp;</td><td><input name=»submit» type=»submit» value=»Submit»></td></tr>
</table>
</form>
</body>
</html>
<?php
}
?>

Во первых тут стоит указать что вывод html и ошибок происходит в функции doIndex() которая вызывается в некоторых случаях, это не очень удобно поэтому кто хочет переписать — милости прошу, лично я сделал это для примера, к каждому проекту я пишу собственную авторизацию и стараюсь не повторяться. Поэтому здесь только пример.

А теперь по порядку.
1. подключаем конфиг
2. если уже авторизованы пересылаем на страницу members.php ( функция checkLoggedIn с параметром no )
3. Если отправлена форма, проверяем поля валидатором, если есть ошибки вызываем функцию doIndex(), если пароли не совпадают ставим ошибку, если есть ошибки вызываем функцию doIndex(), если все в порядке ставим сессию и отправляем на members.php, иначе опять вызываем функцию doIndex()
4. Функция doIndex() выводит html код, ошибки и форму для авторизации.

logout.php

1
2
3
4
5
6

<?php
include_once(«config.php»);
checkLoggedIn(«yes»);
flushMemberSession();
header(«Location: login.php»);
?>

Тут все просто:
1. Подключаем конфиг
2. Проверяем авторизован ли пользователь
3. Уничтожаем сессию
4. Отправляем пользователя на страницу авторизации

members.php

1
2
3
4
5
6
7

<?php
include_once(«config.php»);
checkLoggedIn(«yes»);
print(«<b>».$_SESSION[«login»].»</b>! Добро пожаловать<br>\n»);
print(«Ваш пароль: <b>».$_SESSION[«password»].»</b><br>\n»);
print(«<a href=\»logout.php».»\»>Выход</a>»);
?>

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

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

Теги: function, MySQL, PHP, Авторизация

programmer-weekdays.ru

Пишем авторизацию пользователя на PHP — Блог веб-разработчиков

Совсем недавно я рассказывал, как при помощи PHP написать

систему регистрации для своего сайта. Такой же принцип мы использовали и в своём проекте, созданию которого посвящён раздел «Сайт с нуля» на этом блоге (сам проект я покажу вам гораздо позже). Сегодня же я опишу, как написать авторизацию на сайте, используя данные, полученные от пользователя при регистрации. То есть, будет использоваться таблица MySQL, структура которой была описана в статье про регистрацию. Поэтому я настоятельно рекомендую прежде прочитать ту статью, ибо данная статья является её непосредственным продолжением. Авторизация будет работать с использованием сессий и cookie. Также в статье будет рассмотрено несколько приятных дополнений, таких, как «разлогинивание» (выход) и время последней активности пользователя. Итак, приступим…

Для начала необходимо сверстать главную страницу сайта и поместить её в корне сайта в папку template. Для данного урока нам достаточно, чтобы в этом файле была форма ввода логина и пароля, а также кнопка «Вход». Далее приведён код этой формы:

1
2
3
4
5
<form action="/" method="post">
 Логин: <input type="text" name="login" />

 Пароль: <input type="password" name="password" />
 <input type="submit" value="Войти" name="log_in" />

 </form>

Файл назовём index.html.

Метод передачи post необходим. Ведь мы не хотим, чтобы при авторизации логин и пароль светились в адресной строке.

Как только форма готова, создадим самый важный файл будущего сайта — главный контроллер, т. е. файл, лежащий в корне сайта — index.php. Именно он и будет запускаться при входе на сайт. На момент написания статьи на нашем проекте код этого файла занимает 92 строки, нам же понадобится пока лишь около 25 строк. Вот его код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?
include ('lib/connect.php'); //подключаемся к БД
include ('lib/module_global.php'); //подключаем файл с глобальными функциями

 
if($_GET['action'] == "out") out(); //если передана переменная action, «разавторизируем» пользователя
 
if (login()) //вызываем функцию login, определяющую, авторизирован юзер или нет

{
	$UID = $_SESSION['id']; //если юзер авторизирован, присвоим переменной $UID его id
	$admin = is_admin($UID); //определяем, админ ли юзер

}
else //если пользователь не авторизирован, то проверим, была ли нажата кнопка входа на сайт
{
	if(isset($_POST['log_in'])) 
	{
		$error = enter(); //функция входа на сайт

		if (count($error) == 0) //если нет ошибок, авторизируем юзера
		{
			$UID = $_SESSION['id'];

			$admin = is_admin($UID);
		}
	}
}
include ('tpl/index.html'); //подключаем файл с формой

?>

Теперь более подробно разберёмся, как всё это работает.

В первых трёх строках мы просто подключаем файлы с функциями, которые будем использовать далее в коде. О них чуть позже. Далее проверим, был ли передан get-параметр action=out. Если он был передан, значит пользователь нажал на ссылку выхода с сайта. Вот, кстати, код этой ссылки. Добавьте его в файл с кодом формы для входа.

<a href="/?action=out">Выход</a>

Саму функцию, как и все остальные, рассмотрим позже. Сперва логика…

Далее идёт условие, проверяющее авторизирован ли ты (if (login())). Функция возвращает true в случае, если пользователь вошёл на сайт и false в противном случае. Если вернулось true, записываем в переменную $UID id юзера, а в переменную $admin — результат работы функции is_admin($UID). Данная функция определяет, является ли пользователь администратором и возвращает true, если юзер — админ и false в противном случае. В дальнейшем две эти переменные будут необходимы для вывода определённых элементов на странице. Так, следующим условием можно вывести форму авторизации:

1
2
3
4
5
6
7
8
9
10
<?
If($UID) //если переменной нет, выводим форму
{?>
<form action="/" method="post">

Логин: <input type="text" name="login" />
Пароль: <input type="password" name="password" />

<input type="submit" value="Войти" name="log_in" />
</form>
<?}
?>

Аналогично и с переменной $admin. Кстати, последний код можно включить в файл с формой.
Если же функция login() вернёт false, т. е. пользователь не вошёл на сайт, проверим, нажал ли он на кнопку входа на сайт в форме авторизации:

if(isset($_POST['log_in']))

Если да, запускаем функцию enter(), авторизирующую пользователя. Если ошибок не произойдёт и юзер успешно вошёл, создадим те же 2 переменные: $UID и $admin. В противном случае никакие переменные не создаются – пользователь является гостем. Алгоритм работы представлен на следующей схеме:

Теперь разберёмся со всеми функциями, вызываемыми в данном коде. В первую очередь опишу функцию входа на сайт:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

function enter ()
 { 
$error = array(); //массив для ошибок 	
if ($_POST['login'] != "" && $_POST['password'] != "") //если поля заполнены 	

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

	$rez = mysql_query("SELECT * FROM users WHERE login=$login"); //запрашиваем строку из БД с логином, введённым пользователем 		
	if (mysql_num_rows($rez) == 1) //если нашлась одна строка, значит такой юзер существует в БД 		

	{ 			
		$row = mysql_fetch_assoc($rez); 			
		if (md5(md5($password).$row['salt']) == $row['password']) //сравниваем хэшированный пароль из БД с хэшированными паролем, введённым пользователем и солью (алгоритм хэширования описан в предыдущей статье) 						

		{ 
		//пишем логин и хэшированный пароль в cookie, также создаём переменную сессии
		setcookie ("login", $row['login'], time() + 50000); 						
		setcookie ("password", md5($row['login'].$row['password']), time() + 50000); 					
		$_SESSION['id'] = $row['id'];	//записываем в сессию id пользователя 				

		$id = $_SESSION['id']; 				
		lastAct($id); 				
		return $error; 			
	} 			
	else //если пароли не совпали 			

	{ 				
		$error[] = "Неверный пароль"; 										
		return $error; 			
	} 		
} 		
	else //если такого пользователя не найдено в БД 		

	{ 			
		$error[] = "Неверный логин и пароль"; 			
		return $error; 		
	} 	
} 	
 

	else 	
	{ 		
		$error[] = "Поля не должны быть пустыми!"; 				
		return $error; 	
	} 

}

Первым делом, функция проверяет, заполнил ли пользователь поля для ввода логина и пароля. Если да — продолжаем работу программы, если нет — пишем в массив $error текст ошибки и возвращаем его в основную программу, которая, узнав размерность полученного массива, не авторизирует пользователя.
Если же работа функции enter() продолжится, проверим, существует ли в БД запись с таким ником, какой ввёл юзер. Если такой записи не оказалось, вернём опять же массив с соответствующей ошибкой. Если в БД есть один пользователь с таким ником, сравним введённый пароль с паролем, хранящимся в базе данных и соответствующим нашему нику.

Сравниваем мы пароли не в чистом виде. Ведь в БД они хранятся хэшированными функцией md5(). Поэтому, прежде чем сравнивать их, необходимо тем же алгоритмом хэшировать и введённый пользователем при авторизации пароль. Если хэши совпадут, значит логин и пароль совпали и скрипт авторизирует пользователя. Если совпадения не произошло, вернём ошибку.

Теперь объясню, что же значит «авторизироваться». В данном скрипте данные об авторизации хранятся в сессии и cookie. В сессию записываем id пользователя:

И создаём два cookie: login и password с продолжительностью жизни — 50000 секунд. В первый пишем логин, а во второй — хэш пароля.

В этой строке мы выполняем функцию, отвечающую за установку времени последней активности юзера. Вот код этой функции:

1
2
function lastAct($id)
{ 	$tm = time(); 	mysql_query("UPDATE users SET online='$tm', last_act='$tm' WHERE"); }

Функция перезаписывает поля online и last_act в БД. Кстати, предварительно, необходимо убедиться в существовании этих полей. Оба они имеют тип int.

Алгоритм работы функции enter() приведён на следующей иллюстрации:

Следующая функция отвечает за проверку, авторизирован ли пользователь на сайте или нет — login().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
function login () { 	
ini_set ("session.use_trans_sid", true); 	session_start();  	if (isset($_SESSION['id']))//если сесcия есть 	

{ 		
if(isset($_COOKIE['login']) && isset($_COOKIE['password'])) //если cookie есть, то просто обновим время их жизни и вернём true 		{ 			
SetCookie("login", "", time() - 1, '/'); 			SetCookie("password","", time() - 1, '/'); 			

setcookie ("login", $_COOKIE['login'], time() + 50000, '/'); 			

setcookie ("password", $_COOKIE['password'], time() + 50000, '/'); 			

$id = $_SESSION['id']; 			
lastAct($id); 			
return true; 		

} 		
else //иначе добавим cookie с логином и паролем, чтобы после перезапуска браузера сессия не слетала  		
{ 			
$rez = mysql_query("SELECT * FROM users WHEREid']}'"); //запрашиваем строку с искомым id 			

if (mysql_num_rows($rez) == 1) //если получена одна строка 			{ 		
$row = mysql_fetch_assoc($rez); //записываем её в ассоциативный массив 				

setcookie ("login", $row['login'], time()+50000, '/'); 				

setcookie ("password", md5($row['login'].$row['password']), time() + 50000, '/'); 

$id = $_SESSION['id'];
lastAct($id); 
return true; 			

} 
else return false; 		
} 	
} 	
else //если сессии нет, то проверим существование cookie. Если они существуют, то проверим их валидность по БД 	
{ 		
if(isset($_COOKIE['login']) && isset($_COOKIE['password'])) //если куки существуют. 		

{ 			
$rez = mysql_query("SELECT * FROM users WHERE login='{$_COOKIE['login']}'"); //запрашиваем строку с искомым логином и паролем 			
@$row = mysql_fetch_assoc($rez); 			

if(@mysql_num_rows($rez) == 1 && md5($row['login'].$row['password']) == $_COOKIE['password']) //если логин и пароль нашлись в БД 			

{ 				
$_SESSION['id'] = $row['id']; //записываем в сесиию id 				
$id = $_SESSION['id']; 				

lastAct($id); 				
return true; 			
} 			
else //если данные из cookie не подошли, то удаляем эти куки, ибо нахуй они такие нам не нужны 			
{ 				
SetCookie("login", "", time() - 360000, '/'); 				

SetCookie("password", "", time() - 360000, '/');	 				
return false; 			

} 		
} 		
else //если куки не существуют 		
{ 			
return false; 		
} 	
} 
}

Почему для авторизации мы будем использовать и COOKIE и сессию? Дело в том, что после закрытия браузера, сессия «умирает» и пользователь автоматически разлогинивается. Cookie же хранятся определённое, задаваемое нами, время. В данном случае это 50000 секунд.

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

Функция вернёт true, если юзер авторизирован и false в противном случае. Пичём, в процессе её работы, будет обновлено время жизни cookie, а также они будут созданы, если не существуют.

Лучше всего работу функции online описывает эта иллюстрация:

Если есть сессия и cookie, мы обновляем время жизни cookie. Для этого мы их удаляем, устанавливая время смерти на одну секунду раньше текущего момента времени, а затем устанавливаем заново. Также функцией lastAct() обновлем время последней активности. Возвращаем true.

Если же сессия есть, а cookie по какой-то причине не оказалось, то по id пользователя получаем из БД логин и хэш пароля и пишем их в cookie. Возвращаем true.

Если нет сессии, проверим, быть может существуют cookie. Классический пример авторизации после перезапуска браузера — сессия слетела, но cookie-то живы. Тут уже сложнее, мы должны проверить, совпадает ли пара логин-пароль с какой-либо строкой из БД. Ведь юзер мог заменить в настройках для сайта cookie ручками или написать любую чушь. Если такая пара нашлась, создаём переменную сессии и возвращаем true. Если же пара не найдена, посылаем пользователя на йух и возвращаем false.

Последний, самый печальный вариант — когда ни сессии, ни cookie не оказалось… Возвращаем false.

Теперь обратим взор на функцию is_admin($UID). Она определяет, является ли юзер администратором сайта. Возможно, вам это не нужно, тогда можете опустить эту функцию и все её вызовы в контроллере. Но она может быть полезна для вывода какого либо контента на страницу, предназначенного для администраторов, а не для обычных пользователей. Функция простая и основана на ещё одном созданном столбце в БД в таблице users. Столбец называем prava. Тип int. Если юзер является обыкновенным пользователем, то присваиваем значению в этом столбце 0, если же этот юзер — админ, то присваиваем единицу. Следующая функция и определяет, что стоит в столбце prava; если единица, то возвращается true (пользователь – админ), иначе false.

1
2
3
4
5
6
7
8
9
10
function is_admin($id) { 	
@$rez = mysql_query("SELECT prava FROM users WHERE"); 	

if (mysql_num_rows($rez) == 1) 	
{ 		
$prava = mysql_result($rez, 0); 		

if ($prava == 1) return true; 		
else return false; 

} 	
else return false;	 
}

Ну и последняя, на самом деле очень лёгкая, функция — out(). Принцип её работы прост — удалить все «следы» пользователя – сессию и cookie.

1
2
3
4
5
6
7
8
function out () { 	
session_start(); 	
$id = $_SESSION['id'];			 	

mysql_query("UPDATE users SET online=0 WHERE"); //обнуляем поле online, говорящее, что пользователь вышел с сайта (пригодится в будущем) 	
unset($_SESSION['id']); //удаляем переменную сессии 	
SetCookie("login", ""); //удаляем cookie с логином 	

SetCookie("password", ""); //удаляем cookie с паролем  	
header('Location: http://'.$_SERVER['HTTP_HOST'].'/'); //перенаправляем на главную страницу сайта }

Код всех описанных функций помещаем в файл lib/module_global.php, который подключается в самом начале работы контроллера.

Таким образом, мы написали простую, однако достаточно функциональную регистрацию для своего будущего сайта. В придачу ко всему мы заложили некоторый фундамент для ещё не рассмотренных возможностей: администрирование, онлайн-пользователи, время последней активности. Также авторизация не будет слетать после перезапуска браузера, что достигнуто путём использования cookie. Кроме этого мы предусмотрели и выход с сайта.

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

Чтобы не пропустить следующие статьи, подпишитесь на RSS.

Удачи и до следующих статей.

true-coder.ru

Авторизация пользователя в PHP

Здравствуйте уважаемый посетитель!

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

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

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

Данная статья представляет собой вводную часть нового радела «Авторизация пользователей», в котором предполагается рассмотреть все основные вопросы, связанные с созданием на сайте полноценного механизма авторизации.

И конечно, нельзя забывать о безопасности при работе с разграничением прав доступа. Поэтому в этом разделе мы обязательно уделим внимание и этому немаловажному вопросу.

  • Зачем нужны сессии и cookies
  • Использование сессий и cookies в механизме авторизации
  • Как узнать текущие настройки PHP
  • Как изменить параметры настроек сессий
  • Где хранятся файлы сессий и как посмотреть их содержимое
  • Как посмотреть данные cookies
  • Исходные файлы сайта

Зачем нужны сессии и cookies


В нашем варианте при построении системы авторизации будем использовать так называемые PHP-сессии (session). Которые по существу представляют собой способы хранения информации на сервере в виде уникальных для каждого пользователя переменных.

Кроме того потребуется использование и других данных, находящихся в так называемых файлах «cookies» (куки). Представляющие небольшие фрагменты, отправляемые веб-сервером, и предназначенные для хранения в браузере пользователя.

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

С чем нам прийдется работать, мы определили — это сессии и cookies. А теперь попробуем ответить на вопрос, а зачем они нужны для авторизации и можно ли обойтись без них.

Сложность работы с веб-ресурсом при авторизации состоит в том, что протокол HTTP не поддерживает сохранение данных между загрузками веб-страниц. И соответственно, основываясь только на средствах, предоставляемых этим протоколом, нельзя определить, какие запросы относятся к каким пользователям.

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

И вот одним из элементов PHP, который решает данную проблему, являются сессии. Которые в отличие от обычных PHP-переменных могут быть сохранены и доступны при любом запросе пользователя.

Это особенность сессий и позволяет использовать сохраненные в них данные на всем отведенном промежутке времени работы пользователя с веб-ресурсом, включая повторные загрузки веб-страниц.

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

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

И в таком случае посетителю не потребуется при очередных загрузках страниц повторно отправлять форму со своим логином и паролем. Так как вся необходимая для авторизации информация будет находиться в файлах сессий на сервере и в сохраненных данных cookies браузера.

А для того, чтобы все это работало должным образом, необходимо при использовании сессий и cookies обеспечить необходимое взаимодействие между сервером и браузером.

Использование сессий и cookies в механизме авторизации


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

При этом для каждого пользователя предусмотрено использование необходимых для авторизации данных, сохраняемых в глобальных переменных массива $_SESSION.

И что важно, эти данные доступны при каждом последующем обращении пользователя с возможностью записи/чтения значений логина и пароля (возможно использование и других переменных).

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

В любом случае при запуске сессии формируется уникальный идентификатор, состоящий из случайного 32-ух значного шестнадцатеричного числа, к примеру: «a6kms4aussieqv4daa78i5a9qm3t988h». При этом для хранения данных сессии на сервере создается файл, имя которого соответствует идентификатору с добавлением префикса «sess_». Для вышеуказанного идентификатора, имя файла будет иметь следующий вид: «sess_a6kms4aussieqv4daa78i5a9qm3t988h».

Кроме этого сервер должен передать, а браузер увидеть и сохранить этот идентификатор у себя в сессионной cookie с именем «PHPSESSID». Это имя по умолчанию определяется директивой «session.name» конфигурационного файла «php.ini». При желании имя можно изменить (позднее посмотрим как это можно сделать).

А далее при повторных запросах браузер будет передавать серверу ранее сохраненную сессионную cookie, по которой сервер сможет однозначно определить кто сделал запрос: тот же человек, который ранее был авторизован, или некто другой. И в зависимости от этого выбирать нужный файл сессии для работы с этим пользователем.

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

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

Очевидно, что при множестве различных вариантов довольно сложно рассказать о механизме авторизации «на пальцах» с помощью только текстового описания. Поэтому, более подробно об этом можно будет поговорить, когда мы перейдем к непосредственному созданию на сайте системы авторизации. Где подробно, с приведением соответствующего PHP-кода, будет рассмотрен каждый этап практического использования ее элементов.

А сейчас посмотрим как можно узнать о текущих настройках PHP, определяющих основные параметры сессий и cookies.

Как узнать текущие настройки PHP


Очевидно, что для того, чтобы полноценно работать с сессиями и файлами cookies, необходимо иметь информацию об их текущих настройках. Поэтому в этой части мы попробуем выяснить относящиеся к ним настройки конфигурации PHP.

Узнать это можно разными способами. В первую очередь мы посмотрим, как это можно сделать с помощью функции phpinfo(). Которая предназначена для вывода информации о текущей конфигурации. И обычно используется в для проверки настроек конфигурации и для просмотра доступных предопределенных констант в системе.

Данный способ хорош тем, что позволяет в достаточно удобном для просмотра табличном виде вывести в окне браузера полную информацию о текущем состоянии PHP, включая информацию о настройках компиляции PHP, о расширениях, о версии, информацию о сервере и среде выполнения, окружении PHP, версии ОС, о путях, об основных и локальных значениях настроек конфигурации, о HTTP заголовках и лицензии PHP.

Для этого достаточно создать отдельный файл, например с именем info.php, разместив его в корне сайта, и записать в него всего лишь одну строку кода.

Рис.1 Функция для определения текущей конфигурации PHP

И теперь, если в браузере ввести домен сайта с указанием в адресе наименования этого файла, например для сайта «newsite.local»: newsite.local/info.php, то должна отобразиться страница с полной информацией о конфигурации PHP.

На следующем скриншоте показан фрагмент конфигурации с интересующими нас настройкам расширения «session» для сайта «newsite.local».

Рис.2 Фрагмент конфигурации PHP с настройками раздела session

Следует обратить внимание, что в этой таблице имеется две колонки — Master Value и Local Valu, в которых указываются следующие значения параметров:

  • Master Value — указывается те значения, которые записаны в конфигурационном файле php.ini, и применяются при запуске PHP в соответствии с установленными директивами;
  • Local Value — отображается текущее значение, которое определяется с учетом применения любых переопределений, произведенных либо через директивы файла .htaccess дополнительной конфигурации веб-сервера Apache, распространяющиеся на все страницы соответствующего домена, либо с помощью вызовов PHP-функций, устанавливающих нужные настройки при выполнении определенных скриптов.

Что касается описанием настроек, относящихся к сессиям, то для этого лучше использовать соответствующий раздел документации по PHP, в котором перечислены все возможные опции с установками по умолчанию и приведен по каждой из них краткий обзор, как показано в следующей выдержке из документации.

скриншот 43

rabota-vinete.ru

Читать онлайн Курс «Язык программирования PHP»

Menu Menu Auth Онлайн Библиотека
  • Авторизация
    • OdnoklassnikiMailruYandexGoogleFacebook
Поиск Фантастика 7408Детективы и Триллеры 8301Проза 2228Любовные романы 10604Приключения 6423Детское 7693

litra.info

Иллюстрированный самоучитель по PHP › Авторизация доступа › Авторизация с помощью сессий [страница — 52] | Самоучители по программированию

Авторизация с помощью сессий

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

В связи с этим возникает вопрос: а нельзя ли как-нибудь избежать необходимости каждый раз осуществлять проверку логина и пароля посетителя? Чтобы, единожды авторизовав посетителя, впоследствии предоставлять ему доступ на страницы защищенной зоны без каких-либо проверок? Именно так, кстати, действует защита на основе средств web-сервера – файлов .htaccess, описанная в первом разделе главы. Но можно ли сделать то же самое средствами РНР? Да и вообще использовать cookie для хранения паролей не очень желательно: его содержимое может узнать любой, кто воспользуется компьютером, на котором этот cookie сохранен (многие браузеры хранят cookie в предназначенной для них папке, даже если «время жизни» cookie истекло и он больше не принимается сервером).

Напрашивается первое предложение: а почему бы, например, после успешной авторизации не отправить посетителю cookie с какой-либо пометкой (например, устанавливать в 1 значение переменной в этом cookie), а впоследствии проверять не наличие записанных в cookie логина и пароля в файле паролей или базе данных, а присутствие в cookie этой самой пометки, одинаковой для всех, прошедших авторизацию? Или даже сделать разные типы пометок и в зависимости от типа предоставлять посетителю разные возможности на сайте?

Сделать-то так можно, да вот устойчивость такой системы авторизации к взлому будет не особо великой. Злоумышленнику будет достаточно узнать, что за пометку помещает сценарий авторизации в cookie, чтобы получить к защищенной зоне полный доступ – просто вручную создав такой cookie. (А если при проверке «пометки» использовался не элемент массива $HTTP_COOKIE_VARS, а одноименная переменная, то и просто подставив ее значение в адресной строке при заходе на страницу с такой проверкой: например, page .php?auth=1.) Кроме того, просмотреть значение cookie на компьютере посетителя и узнать, какие его имя и значение являются «пометкой», тоже не так трудно.

Но самое главное – посетители нередко отключают использование cookie при своих путешествиях по Интернету. При отключенных cookie описанная выше система авторизации на их основе работать не будет.

Как же быть?

Следует использовать весьма интересный механизм сессий, появившийся в 4-й версии РНР.

samoychiteli.ru

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *