За последние 24 часа нас посетили 15936 программистов и 1581 робот. Сейчас ищут 667 программистов ...

Авторизация, сессии и cookies

Тема в разделе "Сделайте за меня", создана пользователем jammeal, 14 май 2016.

  1. jammeal

    jammeal Новичок

    С нами с:
    14 май 2016
    Сообщения:
    9
    Симпатии:
    0
    Срочно нужно сделать проект, а с php почти не знаком. Помогите, пожалуйста!
    БД в MySQL. Ее сделали до меня. Привожу таблицы внизу.

    Нужно написать скрипты:
    1). Авторизация.
    Проверка, есть ли юзер с такими логином и паролем.
    Если есть, создать сессию. Как сохранить ее в БД? Так, чтобы можно было возобновить, обновив ее дату и время? Сессия должна храниться неделю после последнего сеанса работы с ней. Группу доступа запомнить в ней.
    Создать cookies.
    Отправить на главную страницу сайта.

    2). Скрипт входа.
    Проверка, есть ли cookies. Если да:
    Как связать cookies с сессией и запустить ее, обновив ее дату и время?
    Если нет: отправить на страницу авторизации.
    И далее, опять же, перенаправить на главную сайта.


    create table if not exists t_accounts(
    acc_id int(11) not null auto_increment,
    pass varchar(32) not null,
    login varchar(64) not null,
    primary key (acc_id),
    unique index login_UNIQUE(login ASC)

    create table if not exists t_groups(
    group_id int(11) not null auto_increment,
    group_name varchar(64) not null,
    primary key (group_id)

    create table if not exists t_rules(
    rule_id int(11) not null auto_increment,
    rule_descr varchar(255) character set 'utf8' not null,
    primary key (rule_id)

    create table if not exists t_sessions(
    session_id int(11) not null,
    session_date DATETIME NOT NULL,
    session_data text not null

    create table if not exists t_rules_accounts(
    rule_id int(11) not null,
    acc_id int (11) not null,
    index fk_t_rules_accounts_t_rules1 (rule_id ASC),
    index fk_t_rules_accounts_t_accounts1 (acc_id ASC),
    constraint fk_t_rules_accounts_t_rules1
    foreign key (rule_id)
    references security.t_rules(rule_id)
    on delete cascade
    on update cascade,
    constraint fk_t_rules_accounts_t_accounts1
    foreign key (acc_id)
    references security.t_accounts(acc_id)
    on delete cascade
    on update cascade

    create table if not exists t_rules_groups(
    rule_id int(11) not null,
    group_id int (11) not null,
    index fk_t_rules_groups_t_groups1 (group_id ASC),
    index fk_t_rules_groups_t_rules1 (rule_id ASC),
    constraint fk_t_rules_groups_t_groups1
    foreign key (group_id)
    references security.t_groups(group_id)
    on delete cascade
    on update cascade,
    constraint fk_t_rules_groups_t_rules1
    foreign key (rule_id)
    references security.t_rules(rule_id)
    on delete cascade
    on update cascade

    create table if not exists t_acc_groups(
    acc_id int(11) not null,
    group_id int(11) not null,
    index fk_t_acc_groups_t_accounts1 (acc_id ASC),
    index fk_t_acc_groups_t_groups1 (group_id ASC),
    constraint fk_t_acc_groups_t_accounts1
    foreign key (acc_id)
    references security.t_accounts(acc_id)
    on delete cascade
    on update cascade,
    constraint fk_t_acc_groups_t_groups1
    foreign key (group_id)
    references security.t_groups(group_id)
    on delete cascade
    on update cascade
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Слишком много для халявы, может перенести в раздел free-lance? Там могут сделать за деньги.
     
  3. jammeal

    jammeal Новичок

    С нами с:
    14 май 2016
    Сообщения:
    9
    Симпатии:
    0
    Буду рад, если мне ответят здесь хоть на какие-то из вопросов. Сам пытаюсь разбираться. Но любой дельный ответ облегчит задачу.
     
  4. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Это всё есть в книгах по PHP для начинающих.

    Разбей задачи на простые шаги.
    Создай страничку с двумя формами для логина и пароля, кнопку отправить.
    Сделай так чтобы она отправлялась на обработчик php.
    Потом уже можно будет поговорить о базе данных.
     
  5. jammeal

    jammeal Новичок

    С нами с:
    14 май 2016
    Сообщения:
    9
    Симпатии:
    0
    Это уже сделал. Написал функции входа и авторизации. Но они, кажется, неработоспособные.
    Подскажете, что неверно. Как несильно менять, чтобы работало?
    PHP:
    1. //Вход
    2. include 'authorization.php';
    3. function EatCookie(){
    4.     $result=false;
    5.     $hash=isset($_COOKIE['site_hash'])?explode('::',$_COOKIE['site_hash']):($result=false);
    6.     $id=$hash[0];
    7.     $hash=$hash[1];
    8.     $conn_id=mysql_connect('localhost','root','','rup');
    9.     mysql_select_db('database');
    10.     if(!is_numeric($id)){
    11.         $result=false;
    12.     }else{
    13.         $q=mysql_query("SELECT * FROM 't_accounts' WHERE acc_id='".$id."'",$conn_id);
    14.         if(mysql_numrows($q)==0){
    15.             $result=false;
    16.         }else{
    17.             $row=mysql_fetch_assoc($q);
    18.             $newHash=md5(md5($row['login']).md5($row['pass']));
    19.             if($newHash==$hash){
    20.                 $result=true;
    21.             }else{
    22.                 $result=false;
    23.             }
    24.         }
    25.     }
    26.     //return $result;
    27.  
    28.     if($result==false){header("Location: page1.php");} //перенаправляем на страницу авторизации
    29.     else {//вытащить сессию, обновить и перенаправить на главную
    30.     //подключимся к БД. Здесь будет инструкция.
    31.     session_start();
    32.     $sess_id=session_id();
    33.     $current_time = time();
    34.  
    35.     $query = "UPDATE t_sessions set session_date='.$current_time.' WHERE session_id='.$sess_id.'";
    36.  
    37.     header("Location: main.php");
    38. }
    39. }
    40.  
    41.  
    42. function authorization($login, $pass) {
    43. //устанавливаем начальное значение авторизации
    44. $user_login=FALSE;
    45. //запрос к базе данных
    46. $q="SELECT * FROM t_accounts WHERE login ='$login'";
    47. $pass=md5($pass);
    48. //проверяем, совпадают ли пары логин-пароль введенные пользователем с теми что в таблице users
    49. if ($login==$auth['login'] and $pass==$auth['password']) {
    50. $_SESSION['username']=$auth['login'];  
    51. $user_login=TRUE;
    52.  
    53. //сохраняем группу доступа пользователя в сессии, чтобы в дальнейший код выполнялся в соответствии с этой группой
    54. $accid = "SELECT acc_id FROM t_accounts WHERE login = '$login' AND pass = '$pass'";
    55. $r = "SELECT group_id FROM t_acc_groups WHERE acc_id = '$accid'";
    56. $_SESSION['right']=$r;
    57.  
    58. //Сохраняем сессию в Базу данных
    59. $sess_id=session_id();
    60. $current_time = time();
    61. $sess_data=session_decode();
    62. $query = "INSERT INTO t_sessions (session_id, session_date, session_data) VALUES ('$sess_id', '$current_time', '$sess_data'";
    63.  
    64. //Создаем cookies  
    65. setcookie('site_hash',$hash,$stime*3600*60);
    66.  
    67. //Отправляем на главную
    68. header("Location: main.php");
    69.  
    70. }
    71.  
    72. else if ($login!=$auth['login']||md5($password)!=$auth['password']){
    73. $error_auth="Неверный логин или пароль";
    74. $user_login=FALSE;
    75. $_SESSION['auth']=FALSE;
    76. }
    77.  
    78. //return $user_login;
    79. }
     
  6. RomanForoschuk

    RomanForoschuk Новичок

    С нами с:
    14 май 2016
    Сообщения:
    9
    Симпатии:
    0
    Во-первых, используй MySQLi или PDO... А скрипт думать надо, а мне лень...
     
  7. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Ну если ты написал этот код, то ты его постепенно писал надеюсь. Вот в какой-то момент, что то перестало работать. Когда это произошло?
    Тут нужно отладку делать, перепроверять, чтобы всё работало, даже маленькая часть. Разбить задачу на части.
    Отладка http://phpfaq.ru/debug

    Когда перестало работать?
     
  8. RomanForoschuk

    RomanForoschuk Новичок

    С нами с:
    14 май 2016
    Сообщения:
    9
    Симпатии:
    0
    Если не тяжело сделай скрин структуры базы данных...
     
  9. jammeal

    jammeal Новичок

    С нами с:
    14 май 2016
    Сообщения:
    9
    Симпатии:
    0
    Эти 6. И еще отдельно таблица session с 3 полями, не с чес не связанная
     

    Вложения:

  10. RomanForoschuk

    RomanForoschuk Новичок

    С нами с:
    14 май 2016
    Сообщения:
    9
    Симпатии:
    0
    Зачем записывать сессию в БД? По-моему это только додаст геморроя... Если вы хотите галочку "Онлайн", почему не создать столбец "status" и при входе ставить значение "1" при выходе "0", или поставить таймер отклика пользователя, и автоматически обновлять запись?

    auth.php
    PHP:
    1. <?php
    2. if ($_SERVER["REQUEST_METHOD"] == "POST" && $_POST["auth"] == "authorization") {
    3.     $success = "";
    4.     $error = basename(__FILE__);
    5.     define("db_host", "localhost");
    6.     define("db_user", "");
    7.     define("db_pass", "");
    8.     define("db_name", "");
    9.     define("db_table", "t_accounts");
    10.  
    11.     $crypt_pass = md5($_POST["pass"]);
    12.     $found = false;
    13.     $id = "";
    14.     $session_timeout = 600;
    15.  
    16.     $mysqli = mysqli_connect(db_host, db_user, db_pass, db_name);
    17.     $mysqli->set_charset("utf8");
    18.  
    19.     if (!$mysqli) {
    20.         printf("Невозможно подключиться к базе данных. Код ошибки: %s\n", mysqli_connect_error());
    21.         exit;
    22.     }
    23.  
    24.     mysqli_select_db($mysqli, db_name);
    25.     $query = "SELECT pass, acc_id, active FROM ". db_table." WHERE login = '". mysqli_real_escape_string($mysqli, $_POST["login"])."'";
    26.     $result = mysqli_query($mysqli, $query);
    27.     if ($data = mysqli_fetch_array($result)) {
    28.         if ($crypt_pass == $data["pass"] && $data["active"] != 0) {
    29.             $found = true;
    30.             $id = $data["acc_id"];
    31.         }
    32.     }
    33.     mysqli_close($mysqli);
    34.     if($found == false) {
    35.         header("Location: ".$error);
    36.         exit;
    37.     } else {
    38.         if (session_id() == "") {
    39.             session_start();
    40.         }
    41.         $_SESSION["login"] = $_POST["login"];
    42.         $_SESSION["acc_id"] = $id;
    43.         $_SESSION["expires_by"] = time() + $session_timeout;
    44.         $_SESSION["expires_timeout"] = $session_timeout;
    45.         $rememberme = isset($_POST["rememberme"]) ? true : false;
    46.    
    47.         if ($rememberme) {
    48.             setcookie("login", $_POST["login"], time() + 3600*24*7);
    49.             setcookie("pass", $_POST["pass"], time() + 3600*24*7);
    50.         }
    51.    
    52.         header("Location: ".$success);
    53.         exit;
    54.    }
    55. }
    56. $login = isset($_COOKIE["login"]) ? $_COOKIE["login"] : "";
    57. $pass = isset($_COOKIE["pass"]) ? $_COOKIE["pass"] : "";
    58. ?>
    59. <!DOCTYPE html>
    60. <html>
    61. <head>
    62.     <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    63.     <title>Вход</title>
    64. </head>
    65. <body>
    66. <h1>Авторизация</h1>
    67. <form action="<?php echo basename(__FILE__); ?>" id="authorization" method="post" name="authorization">
    68.     <input name="auth" type="hidden" value="authorization">
    69.     <input name="login" value="<?php echo $login; ?>" placeholder="Логин" required="required" />
    70.     <input name="pass" type="password" value="<?php echo $pass; ?>" placeholder="Пароль" required="required" />
    71.     <button type="submit" >Войти</button>
    72. </form>
    73. </body>
    74. </html>
    session.php (подключить к страницам для проверки авторизирован пользователь или нет. Т.е. " include("path/to/session.php"); ".)
    PHP:
    1. <?php
    2. if (session_id() == "") {
    3.     session_start();
    4. }
    5.  
    6. if (!isset($_SESSION["id"])) {
    7.     header("Location: auth.php");
    8.     exit;
    9. }
    10.  
    11. if (isset($_SESSION["expires_by"])) {
    12.     $expires_by = intval($_SESSION["expires_by"]);
    13.     if (time() < $expires_by) {
    14.         $_SESSION["expires_by"] = time() + intval($_SESSION["expires_timeout"]);
    15.     } else {
    16.         unset($_SESSION["id"]);
    17.         unset($_SESSION["expires_by"]);
    18.         unset($_SESSION["expires_timeout"]);
    19.         header("Location: auth.php");
    20.         exit;
    21.     }
    22. }
    23. ?>
    Доступ только ограниченному кругу лиц
    PHP:
    1. <?php
    2. $users = array("Сюда вставь ID пользователя", "или несколько");
    3. if (!in_array($_SESSION["id"], $users)) {
    4.     header("Location: auth.php");
    5.     exit;
    6. }
    7. ?>
    Кнопка "Выйти"
    PHP:
    1. <?php
    2. if(isset($_GET["logout"])) {
    3.     if (session_id() == "") {
    4.         session_start();
    5.     }
    6.     unset($_SESSION["id"]);
    7.     header("Location: auth.php");
    8. }
    9. ?>
    10. <a href="?logout">Выйти</a>
    Вывод данных из сессии
    PHP:
    1. <?php
    2. function id() {
    3.     if (isset($_SESSION["id"])) {
    4.         echo $_SESSION["id"];
    5.     } else {
    6.         echo "N/A";
    7.     }
    8. }
    9.  
    10. echo id();
    11. ?>
    Мне кажется так проще и надежнее, а возможно и быстрее.

    P.S.: Могут быть ошибки не проверял.
    --- Добавлено ---
    Добавь столбец active tinyint(1) со значением "1" пользователь активен, и "0" разумеется не активен