2015-08-14 21 views
2

我是PHP新手,並且完全用OOP和MVC全新,所以請耐心等待。
我基於一些教程構建了一個簡單的登錄系統,結果令人滿意;我可以訪問我的 controllers->行動只有當我登錄,如果我不是我總是重定向到登錄視圖等。PHP MVC OOP在未登錄時保護瀏覽的內容

問題是:每例如,如果我把在URL localhost/project/views/home.php我得到顯示的視圖。那麼,如果用戶沒有登錄,如何保護我的觀點?

代碼:我的 home.php和幾乎任何其他視圖不包含任何有趣的PHP代碼。只是從 index.php取小部分。

的index.php

<?php 
require_once('connection.php'); 

define("APP_NAME", "Edarati"); 

session_start(); 

if(!isset($_SESSION['name'])) { 
    require_once('controllers/login_controller.php'); 
    require_once('models/user.php'); 
    $login = new LoginController(); 

    $login->login(); 

    if (isset($_GET['action']) && $_GET['action'] == 'register') { 
     $login->register(); 
    } 
} else { 

    // logging out 
    if(isset($_GET['action'])) { 
     if ($_GET['action'] == 'logout') { 
      require_once('controllers/login_controller.php'); 
      require_once('models/user.php'); 
      $login = new LoginController(); 

      $login->logout(); 
      header('Location:index.php'); 
     } 
    } 

    if (isset($_GET['controller']) && isset($_GET['action'])) { 
     $controller = $_GET['controller']; 
     $action  = $_GET['action']; 
    } else { 
     $controller = 'pages'; 
     $action  = 'home'; 
    } 

    require_once('views/layout.php'); 
    ?> 
} 

If you need to see any other file or bit of code let me know! 

<b>login_controller.php</b> 

    <?php 
    class LoginController { 
     public function login() { 
      require_once('views/login/login.php'); 
      if(isset($_POST['login'])) { 
       $usr = new User; 
       $usr->storeFormValues($_POST); 

       if($usr->userLogin()) { 
        $_SESSION['name'] = $usr->username; 
        header('Location:index.php'); 

       } else { 
        // TODO error page 
        echo "error syntaxe page teet teet"; // didnt work idk why 
       } 
      } 
     } 

     public function register() { 
      require_once('views/login/register.php'); 
      if(isset($_POST['register'])) { 
       $usr = new User; 
       $usr->storeFormValues($_POST); 

       if($_POST['password'] == $_POST['conpassword']) { 
        echo $usr->register($_POST); 
       } else { 
        echo "Password and Confirm password not match"; 
       } 
      } 
     } 
     public function logout() { 
      session_start(); 
      session_unset(); 
      session_destroy(); 
     } 
    } 

user.php的

<?php 

class User { 
    public $username = null; 
    public $password = null; 
    public $salt = "Zo4rU5Z1YyKJAASY0PT6EUg7BBYdlEhPaNLuxAwU8lqu1ElzHv0Ri7EM6irpx5w"; 

    public $first_name = null; 
    public $last_name = null; 

    public function __construct($data = array()) { 
     if(isset($data['username'])) $this->username = stripslashes(strip_tags($data['username'])); 
     if(isset($data['password'])) $this->password = stripslashes(strip_tags($data['password'])); 
    } 

    public function storeFormValues($params) { 
     //store the parameters 
     $this->__construct($params); 
    } 


    public function userLogin() { 
     $success = false; 
     try{ 
      $con = Db::getInstance(); 
      $sql = "SELECT * FROM perso WHERE login = :username AND passe = :password LIMIT 1"; 

      $stmt = $con->prepare($sql); 
      $stmt->bindValue("username", $this->username, PDO::PARAM_STR); 
      $stmt->bindValue("password", hash("sha256", $this->password . $this->salt), PDO::PARAM_STR); 
      $stmt->execute(); 

      $valid = $stmt->fetchColumn(); 

      if($valid) { 
       $success = true; 
      } 

      $con = null; 
      return $success; 
     }catch (PDOException $e) { 
      echo $e->getMessage(); 
      return $success; 
     } 
    } 

    public function register() { 
     $correct = false; 
     try { 
      $con = Db::getInstance(); 
      $sql = "INSERT INTO perso(login, passe) VALUES(:username, :password)"; 

      $stmt = $con->prepare($sql); 
      $stmt->bindValue("username", $this->username, PDO::PARAM_STR); 
      $stmt->bindValue("password", hash("sha256", $this->password . $this->salt), PDO::PARAM_STR); 
      $stmt->execute(); 
      return "Registration Successful <br/> <a href='index.php'>Login Now</a>"; 
     }catch(PDOException $e) { 
      return $e->getMessage(); 
     } 
    } 

    public static function getUser($username) { 
     $db = Db::getInstance(); 
     $curUser = new self(); 

     $req = $db->query("SELECT * FROM perso WHERE login = '$username'"); 
     $user = $req->fetch(); 

     $curUser->username = $user['login']; 
     $curUser->first_name = $user['prenom']; 
     $curUser->last_name = $user['nom']; 

     return $curUser; 
    } 

} 

?> 
+0

請發表您的'LoginController'實現。 –

+0

那裏你去Henrique – Anas

+0

從來沒有聽說過laravel身份驗證?它提供了一切開箱即用 – dynamic

回答

1

在MVC中,您希望阻止直接訪問您的視圖,並且請求/響應將通過控制器處理,您將處理您正在討論的用戶身份驗證。

只有當用戶通過身份驗證時,纔想通過控制器呈現視圖。

有很多好的框架可以爲你做到這一點。

+0

所以我一直在探索Laravel和Symfony,那裏有非常有用的東西,但我需要知道一件事情,我將不得不使用其中一個重建我的整個網站?或者有沒有辦法在我的項目中包含驗證位? – Anas

1

你在你的結構有問題。你應該這樣做:

if(!isset($_SESSION['name'])) { 
    require_once('controllers/login_controller.php'); 
    require_once('models/user.php'); 
    $login = new LoginController(); 

    $login->login(); 

    if (isset($_GET['action']) && $_GET['action'] == 'register') { 
     $login->register(); 
    } else { 
     header('Location: /login.php'); 
    } 
} else { 
    if(isset($_GET['action'])) { 
     if ($_GET['action'] == 'logout') { 
      require_once('controllers/login_controller.php'); 
      require_once('models/user.php'); 
      $login = new LoginController(); 

      $login->logout(); 
      header('Location:index.php'); 
     } 
    } 

    if (isset($_GET['controller']) && isset($_GET['action'])) { 
     $controller = $_GET['controller']; 
     $action  = $_GET['action']; 
    } else { 
     $controller = 'pages'; 
     $action  = 'home'; 
    } 

    require_once('views/layout.php'); 

} 

此外,還有一個很老的bug,我從來沒有能夠真正地追查,但我們去。

本機會話在PHP中的工作方式是PHP向瀏覽器發送一個cookie--默認情況下名爲PHPSESSID。瀏覽器存儲這個cookie。您接下來的請求,您的瀏覽器將發送此cookie和PHP引擎將解釋它,並根據此會話ID在服務器中找到您的會話。

在使用會話和使用 header('Location:...')時,PHP可能會有問題。

似乎PHP不會發送該cookie,因爲您使用的是header()。這可能是由於某些緩存優化(延遲或其他)造成的。

要解決此問題,您必須告訴PHP您已完成設置會話信息。這樣,PHP刷新會話cookie,您可以安全地使用header()重定向。

這可以使用session_write_close()函數完成。

public function login() { 
    require_once('views/login/login.php'); 
    if(isset($_POST['login'])) { 
     $usr = new User; 
     $usr->storeFormValues($_POST); 

     if($usr->userLogin()) { 
      $_SESSION['name'] = $usr->username; 
      session_write_close(); 
      header('Location:index.php'); 

     } else { 
      // TODO error page 
      echo "error syntaxe page teet teet"; // didnt work idk why 
     } 
    } 
} 

現在它應該工作。

如果有人有關於此錯誤的更多信息,請發表評論。

+0

設置cookies的數量不會回答「如果用戶未登錄?如何保護我的視圖?」這個問題。這似乎並沒有回答這個問題。 – ComputerDruid

+0

你對@ComputerDruid,我誤解了這個問題。爲這個問題增加了一個答案,但我指出的問題仍然存在。 –

+0

是的,隨時聲明任何其他錯誤。事實上,我只是意識到了恩裏克的錯誤,並將其固定在我的項目中,現在也修復了這個話題。 – Anas