0

したがって、問題は、/MVCTest/manage/dashboard が呼び出されると、認証 (オーセンティケーター クラスのメソッド) が $_SESSION['user_id'] を見つけられないため、オーセンティケーターが失敗し、ユーザーをログイン ページに戻すことです。 .

ただし、以下のアクションを次のように変更すると: action="/MVCTest/manage/login?target=MVCTest/manage/dashboard"

インデックスコントローラーからmanageControllerに同じログイン関数を追加すると、すべて正常に機能しますが、これは、ログインしたいページがあるすべてのコントローラーにログイン関数が必要であることを意味します(これは、ユーザー ダッシュボード)。

では、$_SESSION をコントローラー間で存続させて、ユーザーのログイン/ログアウトを単一のコントローラーで行うにはどうすればよいでしょうか?

まず、いくつかのコード...

action="/MVCTest/index/login?target=MVCTest/manage/dashboard" は、indexController のログイン アクションを呼び出します。

<?php
  Class indexController Extends Core_Controller {

    public function login(){
     $this->registry->authenticator->login($_POST);
    }
  }
?>

オーセンティケータ オブジェクトはブートストラップで作成され、レジストリに割り当てられました。次に、オーセンティケーター オブジェクトについて説明します。

<?php
  Class Authenticator Extends Base_Model {

    public function login($credentials){
  //Select user from the database based on email/username
  try{
    $STH = $this->db->prepare("SELECT * FROM user_account WHERE email = ? OR username = ?");
    $STH->bindParam(1, $credentials['login']);
    $STH->bindParam(2, $credentials['login']);
    $STH->execute();
    while($user = $STH->fetch(PDO::FETCH_OBJ)){
      $password = $user->user_salt.$credentials['password'];
      $password = $this->hashData($password);
      try{
        if($password === $user->password){
          //Active and Verified user exists, set sessions
          $random = $this->generateRandomString();
          //Build the token
          $token = $_SERVER["HTTP_USER_AGENT"] . $random;
          $token = $this->hashData($token);

          //Setup session variables
          session_start();
          $_SESSION["token"] = $token;
          $_SESSION["user_id"] = $user->id;

          //Delete old session records for the user
          $STH = $this->db->prepare("DELETE FROM user_session WHERE user_account_id = ?");
          $STH->bindParam(1, $user->id);
          $STH->execute();

          //Insert new session records for the user
          try{
            $STH = $this->db->prepare("INSERT INTO user_session (user_account_id, session_id, token) 
                                       VALUES (?,'".session_id()."', ?);");
            $STH->bindParam(1, $user->id);
            $STH->bindParam(2, $token);
            $STH->execute();
            header("Location: /{$_GET['target']}");
            exit;
          } catch (PDOException $e){
            file_put_contents(__SITE_PATH."/logs/errors/MySQLErrors", $e->getMessage()."\n", FILE_APPEND);
            die($e->getMessage());
          }                
        } else {
          throw new Exception("Password is incorrect!");
        }
      } catch (Exception $e){
        file_put_contents(__SITE_PATH."/logs/errors/LoginErrors", $e->getMessage()."\n", FILE_APPEND);
        die($e->getMessage());
      }
    }
    //Email/Username not found
    throw new Exception("Email/Username not found!");
  } catch (Exception $e) {
    file_put_contents(__SITE_PATH."/logs/errors/LoginErrors", $e->getMessage()."\n", FILE_APPEND);
    die($e->getMessage());
  } catch (PDOException $e){
    file_put_contents(__SITE_PATH."/logs/errors/MySQLErrors", $e->getMessage()."\n", FILE_APPEND);
    die($e->getMessage());
  }
}      
}
?>

そして最後に、私のmanageController

<?php
  session_name();
  session_set_cookie_params(3600, "/MVCTest/manage/");
  session_start();

  Class manageController Extends Core_Controller {

    public function index() {
      if(isset($_SESSION['user_id'])){
        header("Location: /MVCTest/manage/dashboard");
        exit;
      }
      $this->registry->template->show('manage/index');
    }

    public function dashboard(){
      $this->registry->authenticator->authenticate("/MVCTest/manage/");     
      $this->registry->template->show('manage/dashboard');
    }
  }
?>

私は答えを見つけました。session_name() を終了します。session_set_cookie_params(3600, __SITE_PATH.'/MVCTest/manage/'); 移動中のmanageControllerで session_start(); 公開ログイン機能を追加しながら、拡張 Core_Controller の先頭に。

その結果、すべてのページで誰かがログインできるようになります。ただし、これは悪い習慣だと思います。私が見る問題は、ユーザーがログインしているかどうかに関係なく、すべてのページ呼び出しがセッションを開始することです。これはまずい気がするのですが、何かお勧めはありますか?

4

1 に答える 1

1

このコードを見てください:

//Setup session variables
session_start();
$_SESSION["token"] = $token;
$_SESSION["user_id"] = $user->id;

使用する必要があります

session_start();

ファイルの先頭。

についてもっと読むsession_start

于 2013-05-03T19:58:25.140 に答える